javascript中的继承-寄生组合式继承

  前文说过,组合继承是javascript最经常使用的继承模式,不过,它也有本身的不足:组合继承不管在什么状况下,都会调用两次父类构造函数,一次是在建立子类原型的时候,另外一次是在子类构造函数内部.子类最终会包含父类对象的所有实例属性,但咱们不得不在调用子类构造函数时重写这些属性.请再看一次组合继承的例子:javascript

function SuperType(name){
       this.name=name;
       this.friends=["gay1","gay2"];  
}
SuperType.prototype.sayName=function(){
       alert(this.name);
};
funciton SubType(name,age){
      SuperType.call(this,name); //第二次调用SuperType();
      this.age=age;  
}
SubType.prototype=new SuperType();  //第一次调用SuperType()
SubType.prototype.sayAge=function(){
      alert(this.age);
};

  在第一次调用SuperType构造函数时,SubType.prototype会获得两个属性:name和friends,他们都是SuperType的实例属性.只不过如今位于SubType的原型中.当调用SubType构造函数时,又会调用一次SuperType构造函数,这一次又在新对象上建立了实例属性name和friends.因而,这两个属性就屏蔽了原型中的两个同名属性.java

  结果是,有两组name和friends属性,一组在SubType的实例上,一组在SubType的原型上.这就是调用两次SuperType构造函数的结果.而如今,找到了解决这个问题的方法:寄生组合式继承.函数

  寄生组合式继承:经过借用构造函数来继承属性,经过原型链的混成形式来继承方法.思路:没必要为了指定子类的原型而调用父类的构造函数,咱们所须要的无非就是父类原型的一个副本而已.本质上,就是使用寄生式继承来继承父类的原型,而后在将结果指定给子类的原型:this

function inheritPrototype(subType,superType){
      var prototype=object(superType.prototype); //建立父类原型的一个副本 等同于使用Object.create(superType.prototype)
      prototype.constructor=subType;   //为副本添加constructor属性,弥补重写原型而失去的constructor属性
      subType.prototype=prototype; //将建立的对象(副本)赋值给子类的原型
}

  这样,咱们就能够经过调用inheritPrototype()函数,替换前面例子中为子类原型的赋值语句了:spa

function inheritPrototype(subType,superType){
      var prototype=Object.create(superType.prototype); //建立父类原型的一个副本 等同于使用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方法

var person1=new SubType("nUll",25);
var person2=new SubType("mywei",25);
person1.friends.push("gay3");
person1.sayName();
person1.sayAge();
alert(person1.friends);    //gay1,gay2,gay3
alert(person2.friends); //gay1,gay2
alert(person1 instanceof SubType);   //true
alert(person1 instanceof SuperType);  //true
alert(SubType.prototype.isPrototypeOf(person1));  //true
alert(SuperType.prototype.isPrototypeOf(person1)); //true

  这个例子的高效率体如今它只调用了一次SuperType构造函数,而且所以避免了在SubType.prototype上建立没必要要的 多余的属性.与此同时,原型链还能保持不变.所以,还可以正常使用instanceof 和isPrototypeOf肯定继承关系.prototype

     YUI的YAHOO.lang.extend()方法采用了寄生组合式继承。code

相关文章
相关标签/搜索