原型链继承
原型对象等于另一个类型的实例,也就是子类的原型是父类的实例
function SuperType (name) {
this.property = true;
this.name = name;
}
SuperType.prototype.getSuperValue = function () {
return this.property;
}
function SubType () {
this.subProperty = false;
}
SubType.prototype = new SuperType()
SubType.prototype.constructor = SubType
new SubType('张三')
问题:
- 父类实例上的属性成了原型上的属性
- 在实例化子类的时候(
new SubType('张三')
),无法向父类的构造函数传递参数(SuperType(name)
无法传递name参数)
借用构造函数
通过call或apply方法可以在创建的对象上执行构造函数
function SuperType (name) {
this.property = true;
this.name = name;
}
SuperType.prototype.getSuperValue = function () {
return this.property;
}
function SubType (name) {
SuperType.call(this, name)
this.subProperty = false;
}
new SubType('张三')
虽然解决了原型链继承无法传递参数的问题,但是也有以下问题
问题:
- 方法都在构造函数中定义,因此函数的复用就无从谈起(通常公共的方法会写在原型上,但是没有继承父类原型上的方法,没法复用)
组合继承
原型链+构造函数
function SuperType (name) {
this.property = true;
this.name = name;
}
SuperType.prototype.getSuperValue = function () {
return this.property;
}
function SubType (name) {
SuperType.call(this, name)
this.subProperty = false;
}
SubType.prototype = new SuperType()
SubType.prototype.constructor = SubType
new SubType('张三')
问题:
- 最大的问题在于会调用两次父类的构造函数,一次再子类的构造函数中调用,一次在创建子类的原型上调用,子类的原型会包含父类实例的属性。
原型式继承
借助原型基于已有的对象创建新对象
function SuperType(name) {
this.property = true;
this.name = name;
}
SuperType.prototype.getSuperValue = function () {
return this.property;
}
function SubType(name) {
this.subProperty = false;
}
SubType.prototype = Object.create(SuperType.prototype, { constructor: { value: SubType } })
new SubType('张三')
问题:
- 只继承原型而没有继承实例
寄生式继承
寄生的构造函数以工厂模式类似,用于封装继承的过程
function SuperType(name) {
this.property = true;
this.name = name;
}
SuperType.prototype.getSuperValue = function () {
return this.property;
}
function SubType(name) {
let temp = new SuperType(name)
for (const key in temp) {
if (temp.hasOwnProperty(key)) {
this[key] = temp[key];
}
}
this.subProperty = false;
}
new SubType('张三')
问题:
- 只继承实例而没有继承原型
寄生组合式继承
借用构造函数+原型式继承
function SuperType(name) {
this.property = true;
this.name = name;
}
SuperType.prototype.getSuperValue = function () {
return this.property;
}
function SubType(name) {
SuperType.call(name)
this.subProperty = false;
}
SuperType.prototype = Object.create(SuperType, { constructor: { value: SubType } })
new SubType('张三')