以下内容总结自《JavaScript高级程序设计(第3版)》
一. 组合继承
组合继承使用原型链实现对原型属性和方法的继承,使用借用构造函数实现对实例属性的继承(引用类型的属性写在构造函数里)。
示例:
function SuperType (name) {
this.name = name;
this.colors = ["red", "green", "blue"];
}
SuperType.prototype.sayName = function () {
alert(this.name);
};
function SubType (name, age) {
SuperType.call(this, name); // 第二次调用SuperType构造函数
this.age = age;
}
SubType.prototype = new SuperType(); // 第一次调用SuperType构造函数
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function () {
alert(this.age);
}
根据以上代码,组合继承会调用两次父类构造函数,第一次调用时会将SuperType中的name属性和colors属性写入到SubType的原型中,第二次调用的时候是在创建一个SubType实例的时候,此时会将SuperType中的name属性和colors属性写入到SubType实例中。
相同的属性既被写入了原型中,又被写入了实例中,这是没有必要的。
如何避免两次调用父类构造函数呢?这里使用寄生组合式继承。
二. 寄生组合式继承
function SuperType (name) {
this.name = name;
this.colors = ["red", "green", "blue"];
}
SuperType.prototype.sayName = function () {
alert(this.name);
};
function SubType (name, age) {
SuperType.call(this, name);
this.age = age;
}
// 下面这部分替代给子类原型赋值的过程,不调用父类构造函数,直接继承父类原型
var prototype = Object.create(SuperType.prototype);
prototype.constructor = SubType;
SubType.prototype = prototype;
SubType.prototype.sayAge = function () {
alert(this.age);
}
附:
Object.create()方法是ES5中原型式继承的规范化。
在只传一个参数时,内部行为如下:
function object (o) {
function F() {};
F.prototype = o;
return new F();
}