组合继承
将原型链和借用构造函数的技术组合到一块。
使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。
超类的属性被继承了两次,一次是在子类的构造函数中,使得子类实例拥有各自的属性;一次是在子类的原型中,使得子类拥有相同的属性。
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,black23 instance1.sayName();24 instance1.sayAge();25 26 var instance2 = new SubType("Greg",27); 27 alert(instance2.colors);//red,blue,green28 instance2.sayName();//Greg29 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上面创建不必要的多余的属性。与此同时,原型链还能保持不变。