js中对象继承的方式

1.原型链继承

  1.1

  让对象obj2的原型指向obj1的实例。则说obj2继承了obj1,既obj2.prototype=new obj1( );

        function obj1(){
          this.property1=true;
        }
        obj1.prototype.sayObj1=function(){//方法定义在原型上
           return this.property1;
        }

        function obj2(age){
          this.property2=false;
        }
        //让obj2原型继承obj1,obj2的原型指向obj1的实例
        obj2.prototype=new obj1();
        //给obj2新定义一个方法
        obj2.prototype.sayObj2=function(){
           return this.property2;
        }
        //定义obj2的一个实例
        var instance=new obj2();
        console.log(instance.sayObj1());//true  

 对象创建的时候,实例的属性定义在构造函数中,方法定义在原型中。

最后一句,instance.sayObj1()的过程:首先会在obj2.prototype中查找,若没有找到,则继续在obj1.prototype中查找。

    原因:instance是obj2的实例,其instance._proto_指向构造函数的原型既obj2.prototype,然后再obj2.prototype中没有找到,则继续查找obj2.prototype._proto_,因为obj2.prototype是obj1的一个实例,则obj2.prototype._proto_指向构造函数的原型既obj1.prototype。然后再obj1.prototype中找到了sayObj1.

   注意:原型链的查找记住 实例的_proto_指向的是构造函数的原型(构造函数的prototype),实例与原型有关,与构造函数没有关系。

  注意不要忘记默认的原型链:如下

1.2  怎样确定原型和实例的关系

        instanceof操作符: instance instanceof Object

       isPrototypeOf()方法:obj2.prototype.isPrototypeOf( instance)

1.3  谨慎的定义方法

      顺序:先继承,后添加方法    

        function Obj1(){
          this.property1=true;
        }
        obj1.prototype.sayObj1=function(){//方法定义在原型上
           return this.property1;
        }

        function Obj2(age){
          this.property2=false;
        }
        //让obj2原型继承obj1,obj2的原型指向obj1的实例
        obj2.prototype=new obj1();
        //给obj2添加新的方法
        obj2.prototype.sayObj2=function(){
           return this.property2;
        }
        //对obj2的方法进行了重写
        obj2.prototype.sayObj1=function(){
            return false;
        }
        //定义obj2的一个实例
        var instance=new obj2();
        var instance1=new obj1();
        console.log(instance1.sayObj1());//true
        console.log(instance.sayObj1());//false

注意:当obj2重新了方法的时候,obj2的实例在调用这个方法时调用的是重写后的方法;然而,obj1的实例在调用这个方法时,调用的还是以前的方法。

注意:使用原型链实现继承的时候,不能用对象字面量创建方法,会重写原型链。

如何避免原型链上的对象共享:

    创建一个函数,这个函数里面使用空函数当做中间变量。

var a={name:'m'};
var b=cloneObj(a);
function cloneObj(obj){
  var f=function(){}//空函数
   f.prototype=obj;
return new f();
}

console.log(b.name);

2.构造函数实现继承

  实现原理:在子类型中调用父类型的构造函数。使用call()方法或apply()方法都可以

        function  Parent(){
            this.friend=["a","b"];
        }
        function child(){
            //继承了parent
            Parent.call(this);//将parent中的this绑定到了当前child中的this
        }
        var child1=new Parent();
        child1.friend.push("c");
        console.log(child1.friend)

构造函数继承相比原型继承最大的优点是,子类型在继承了父类型的时候还可以向父类型传递参数。

        function Parent(name){
            this.name=name;
        }
        function  Child(){
            //继承了parent的同时还传递了参数
            Parent.call(this,"xiao");
            this.age=29;
        }
        var  child1=new Child();
        console.log(child1.name);
        console.log(child1.age)

问题:函数无法复用

3.组合继承

实现原理:使用原型链实现原型属性和方法的继承,使用构造函数实现实例属性的继承。

        function Parent(name){
            this.name=name;
            this.colors=["a","b","c"];
        }
        Parent.prototype.sayName=function(){
            return this.name;
        }

        function Child(name,age){
            //继承父类型的属性,用构造函数继承
            Parent.call(this,"xiao");
            this.age=age;
        }
        //继承方法,用原型继承
        Child.prototype=new Parent();//原型继承就把parent的方法就继承过来了
        Child.prototype.constructor=Child;//再让child的原型指回child构造函数
        Child.prototype.sayAge=function(){
            return this.age;
        }
        var  child1=new Child("shanshan",18);  

4.原型式继承  

实现:使用Object.create()方法。

        var person={
            name:"liss",
            friends:["a","b","c"]
        } 
        var anotherPerson=Object.create(person);

 5.寄生式继承

        //类似于工厂模式
        function createAnother(original){//original参数是被继承的对象
            var clone=object(original);//通过调用函数创建一个对象clone
            clone.sayHi=function(){//以某种形式来增强这个对象
                alert("hi");
            };
            return clone;
        }

        var person={
            name:"liss",
            friends:["a","b","c"]
        } 

        var anotherPerson=createAnother(person);//继承了person对象
        anotherPerson.sayHi();

问题:函数不能复用

6.寄生组合继承

寄生组合式继承的基本模式如下: 

        function inheritPrototype(parent,child){
            var prototype=object(parent.prototype);//创建原型对象
            prototype.constructor=child;//让原型对象的构造函数指向child
            child.prototype=prototype;//让child的原型指向parent.prototype
        }
        
        function Parent(name){
            this.name=name;
            this.colors=["a","b"];
        }
        Parent.prototype.sayName=function(){
            return this.name;
        }

        function Child(name,age){
            Parent.call(this,"liss");
            this.age=age;
        }

        inheritPrototype(Parent,Child);
        Child.prototype.sayAge=function(){
            return this.age;
        }

优点:只使用了次parent的构造函数。引用类型最理想的继承范式。

猜你喜欢

转载自blog.csdn.net/L_SS133/article/details/81870812