组合继承与寄生组合式继承
组合继承
将原型链和借用构造函数的技术组合到一块。
使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。
超类的属性被继承了两次,一次是在子类的构造函数中,使得子类实例拥有各自的属性;一次是在子类的原型中,使得子类拥有相同的属性。
1 function SuperType(name){ 2 this.name = name; 3 this.colors = ["red","blue","green"]; 4 } 5 SuperType.prototype.sayName = function(){ 6 alert(this.name); 7 }; 8 9 function SubType(name,age){ 10 //继承属性 11 SuperType.call(this,name);//构造函数继承方法 12 this.age = age; 13 } 14 //继承属性和方法 15 SubType.prototype = new SuperType();//原型链继承 16 SubType.prototype.sayAge = function(){ 17 alert(this.age); 18 }; 19 20 var instance1 = new SubType("Nicholas",29); 21 instance1.colors.push("black"); 22 alert(instance1.colors);//red,blue,green,black 23 instance1.sayName(); 24 instance1.sayAge(); 25 26 var instance2 = new SubType("Greg",27); 27 alert(instance2.colors);//red,blue,green 28 instance2.sayName();//Greg 29 instance2.sayAge();//27
寄生组合式继承
通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。
本质上是,使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型。
1 function object(o){//原型式继承,创建临时构造函数,只继承原型 2 function F(){} 3 F.prototype = o; 4 return new F(); 5 } 6 7 function inheritPrototype(subType,superType){//寄生式继承,创建一个仅用于封装继承过程的函数,在函数内部以某种方式来增强对象,最后返回对象 8 var prototype = object(superType.prototype);//创建对象 9 prototype.constructor = subType;//增强对象 10 subType.prototype = prototype;//指定对象, 11 //subType的原型为prototype,prototype是F的一个实例,而不再是superType的实例,没有superType的属性,prototype的原型为superType.prototype, 12 //subType的原型指向F,F的原型指向superType的原型,F的构造函数指向subType,避免了重复生成SuperType的构造函数属性, 13 //使subType的构造函数继承到superType的属性,subType的原型继承到superType的原型 14 } 15 16 function SuperType(name){ 17 this.name = name; 18 this.colors = ["red","blue","green"]; 19 } 20 SuperType.prototype.sayName = function(){ 21 alert(this.name); 22 }; 23 24 function SubType(name,age){ 25 SuperType.call(this,name); 26 this.age = age; 27 } 28 inheritPrototype(SubType,SuperType); 29 SubType.prototype.sayAge() = function(){ 30 alert(this.age); 31 }
只调用一次SuperType构造函数,避免了在SubType prototype上面创建不必要的多余的属性。与此同时,原型链还能保持不变。