首页 > 代码库 > JS面向对象(2)——原型链

JS面向对象(2)——原型链

原型链用于ECMAScript的继承。其思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。说人话,我们知道,一个构造函数Subtype,其原型对象有一个指向构造函数的指针,这是联系构造函数和原型的桥梁,如果我让原型对象的指针指向了另一个原型,而另一个原型原本指向其构造函数的指针也指向了另一个原型,那么,这就是一个原型链了,原型上的属性会一层一层往下传递。

function SuperType(){        this.property=true;    }    SuperType.prototype.getSuperValue=function(){        return this.property;    };        function SubType(){        this.subproperty=false;    }    //subtype继承了supertype的prototype    SubType.prototype=new SuperType();    SubType.prototype.getSubValue=function(){        return this.subproperty;    };        var instance=new Subtype();        alert(instance.getSuperValue());//true;

所以,继承的实现本质是重写了原型对象。

上面代码中,最后输出了true,原理是:以读取模式访问一个实例属性或方法,现在instance中搜索,搜索不到就沿着原型链往上查找,instance->Subtype.prototype->SuperType.prototype。如果找不到返回undefined.

在JS面向对象(1)中我们已经说到原型链的问题,也就是原型属性是可以被所有实例共享的。解决这个问题的方法可以是借用构造函数,JS高级程序设计上的解释是这种技术的基本思想是:在子类型构造函数的内部调用超类型的构造函数,函数是在特定环境中执行代码的对象,可以通过使用apply()和call()方法在新创建的对象上执行构造函数。这话说的我一愣一愣的0.0  

 1 function SuperType(){ 2         this.color=[‘aa‘,‘bb‘]; 3     } 4      5 function SubType(){ 6       SuperType.call(this); 7 }//继承了SuperType. 8  9 var instance1=new SuperType();10 var instance2=new SuperType();11 instance1.color.push(‘cc‘);12 alert(instance2.color)//[‘aa‘,‘bb‘];没有因为instance1实例修改了color属性而被影响。

1、call可以扩充函数的作用域。

2、call可以传递参数。

第6行的SuperType.call(this),在new SubType时,即创建新对象时,同时执行SuperType构造函数,而且其中的this指向的是实例instance1或者instance2。因此每个实例都会有自己的colors副本。

call传递参数如下

function SuperType(name){        this.color=[‘aa‘,‘bb‘];        this.name=name;    }    function SubType(name){      SuperType.call(this,name);      this.age=20;}//继承了SuperType.var instance1=new SubType(‘a‘);var instance2=new SubType(‘b‘);instance1.color.push(‘cc‘);alert(instance2.color);//[‘aa‘,‘bb‘]alert(instance2.age);//20alert(instance2.name);//b;

组合继承 :使用原型链实现对原型属性和方法的继承(共享),使用构造函数实现对实例属性的继承(独立)。

function SuperType2(name){        this.name=name;        this.colors=[‘red‘,‘green‘];    }    SuperType2.prototype.sayName=function(){        alert(this.name);//prototype的方法会共享给实例    };    function SubType2(name,age){        //继承属性        SuperType2.call(this,name);//借用超类型的构造函数 使每个subtype的实例拥有独立的colors副本,可以修改colors而不会影响其他实例的colors        this.age=age;    }    //继承方法    SubType2.prototype=new SuperType2();//SuperType2的实例赋值给SubType2原型    SubType2.prototype.constructor=SubType2;    SubType2.prototype.sayAge=function(){        alert(this.age);    };    /*SubType2.prototype={        sayAge:function(){            alert(this.age);        }    };*/    var instance3=new SubType2(‘nick‘,20);    var instance4=new SubType2(‘jack‘,30);    instance3.colors.push(‘black‘);    alert(‘组合继承 age:‘+instance3.age);//20    alert(‘instance3自己修改后的的colors:‘+instance3.colors);//[‘red‘,‘green‘,‘black‘];    alert(instance3.name);//nick    instance3.sayName();//nick    instance3.sayAge();//20    instance4.sayName();//jack    instance4.sayAge();//30

SuperType2的实例赋值给SubType2原型,两个不同的instance3和instance4实例拥有自己的属性,name/color/age等,还可以有相同的方法sayAge() sayName()。

组合继承是最常用的继承模式,除此之外还有许多的模式,如原型式继承、寄生式继承等。

 

JS面向对象(2)——原型链