447 字
2 分钟
继承之寄生式组合继承

寄生式组合继承#

在组合式继承的那篇文章说过,组合式继承,会将父类的构造函数调用两次。

本质上,子类原型最终式要包含超类的所有实例属性,子类的构造函数只要在执行适合重写原型就行了

再看看组合式继承的例子

function SuperType(name){
this.name = name;
this.numbers = [1,2,3,4];
}
SuperType.prototype.sayName = function(){
console.log(this.name);
}
function SubType(name, age){
SuperType.call(this, name);
this.age = age;
}
SubType.prototype = new SuperType();
SubType.constructor = SubType;
SubType.prototype.sayAge = function(){
console.log(this.age);
}

这个详细过程如下:

image-20210531170936146

image-20210531171003754

可以看出这里重复调用了SuperType函数。

为了解决这个,引出了了寄生组合式继承

原理#

通过盗用构造函数继承属性,但使用混合式原型链继承的方法。基本思路是不通过调用父类构造函数给子类原型赋值,而是取得父类原型的一个副本。

说到底就是使用寄生式继承来继承父类原型,然后将返回的新对象赋值给子类原型

function inheritPrototype(subType, superType){
let prototype = object(superType.prototype); // 创建对象
prototype.constructor = subType; // 增强对象
subType.prototype = prototype; // 赋值对象
}

inheritPrototype函数接受两个参数,子构造函数和父类构造函数

  1. 创建父类原型的一个副本
  2. 给返回的原型对象设置constructor属性设置为自身,解决原型覆盖丢失constructor的问题
  3. 最后将新创建的对象赋值给子类型的原型

这里只调用了一次父类构造函数,避免了SubType原型上不必要的属性。

而且原型键也保持不变,因此instanceof操作符和isPrototypeOf()方法正常有效。

寄生式组合继承可以算是引用类型继承的最佳模式

继承之寄生式组合继承
https://nollieleo.github.io/posts/继承之寄生式组合继承/
作者
翁先森
发布于
2021-05-31
许可协议
CC BY-NC-SA 4.0