原型链继承:
function SuperType() {
this.color = ['yellow','black','green'];
}
SuperType.prototype.sayName = function () {
console.log(this.name);
};
function SubType(){
}
var instance1=new SubType();
instance1.colors.push('red');
console.log(instance1.colors);//“'yellow','black','green','red'”
var instance2=new SubType();
console.log(instance2.colors);//“'yellow','black','green','red'”
原型链继承有两个问题
1:属性共享,上面的例子中打印的colors一样;
2:创建子类的实例中,不能向超类的构造函数传递参数;
为了解决这两个问题
提出了组合继承
组合继承
function SuperType(name) {
this.name=name;
this.color = ['yellow','black','green'];
}
SuperType.prototype.sayName = function () {
console.log(this.name);
};
function SubType(name,age){
/**增加的点**/
SuperType.call(this,name);//继承属性//第二次调用SuperType()
this.age=age;
}
SubType.prototype=new SuperType();//第二次调用SuperType()
SubType.prototype.constructor=SubType;
组合继承虽然解决了原型链中共享属性问题以及不能向超类的构造函数传递参数问题,但也产生了新的问题
上面的例子中,我们第一次调用SuperType(),SubType.prototype得到了俩属性name、color。第二次调用SuperType(),又在新对象上创建了新的实例属性name、color。这俩属性屏蔽了原型中得name、color。
创建了不必要的多余的属性
为了优化这个问题。
我们可以使用:
寄生组合继承
//继承SuperType的原型
function inheritPrototype(subType,superType){
var prototype=Object.create(superType.prototype);//es6方法
//创建父类原型的一个副本 等同于使用Object.create(superType.prototype)
prototype.constructor=subType;
//为副本添加constructor属性,弥补重写原型而失去的constructor属性
subType.prototype=prototype;
//将创建的对象(副本)赋值给子类的原型
}
function SuperType(name){
this.name=name;
this.friends=["gay1","gay2"];
}
SuperType.prototype.sayName=function(){
alert(this.name);
};
function SubType(name,age){
SuperType.call(this,name); //继承SuperType的属性
this.age=age; //扩展出age属性
}
inheritPrototype(SubType,SuperType);
SubType.prototype.sayAge=function(){
alert(this.age);
};//扩展出sayAge方法
inheritPrototype()函数让子类构造函数继承了超类原型;
SuperType.call(this,name)让子类构造函数继承了超类属性
这个例子的高效率体现在它只调用了一次SuperType构造函数,
并且因此避免了在SubType.prototype上创建不必要的 多余的属性.与此同时,原型链还能保持不变.因此,还能够正常使用instanceof 和isPrototypeOf确定继承关系.
网友评论