425 字
2 分钟
继承之组合继承

组合继承(伪经典继承)#

组合继承综合了原型链和盗用构造函数,将两者的优点集中起来了。

基本思路是:

  1. 使用原型链继承原型上的属性和方法
  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.prototype.sayAge = function(){
console.log(this.age);
}
let instance1 = new SubType('weng', 23);
instance1.numbers.push(5);
console.log(instance1.numbers); // 1,2,3,4,5
instance1.sayName(); // weng
instance1.sayAge(); // 23
let instance2 = new SubType('helloworld', 24);
console.log(instance2.numbers); // 1,2,3,4

用以上的方式创建的实例,可以实现自身的属性是独立的,方法可以是共享的

组合继承是js中用的最多的继承模式

而组合继承也保留了instanceof操作符和isPrototypeOf()方法识别合成对象的能力

可以执行一下语句检验一下,其实这篇文章和原型那块的例子一样,那边更解释了实例和这两个构造函数之间的关系

console.log(SubType.prototype);
console.log(SubType.prototype.isPrototypeOf(instance1));
console.log(SuperType.prototype.isPrototypeOf(instance1));
console.log(SuperType.prototype.isPrototypeOf(SubType.prototype))
console.log(Object.getPrototypeOf(instance1));
console.log(instance1.__proto__);
console.log(instance1.__proto__.constructor);
console.log(SubType.prototype.constructor);

image-20210531160333624

组合继承的问题#

看以上的组合继承代码,你会发现这里的超类也就是SuperType被实例化了两次

  1. 在SubType将其原型覆盖为SuperType构造函数new出来的实例的时候
  2. 在SubType构造函数创建实例的时候,构造函数内部直接调用了SuperType,这里又初始化了一次

造成的问题就是,SuperType创建出来的实例,也就是此时SubType的原型,会带有SuperType构造函数初始化的参数,并且,SubType构造函数创建出来的实例,也会带着SuperType的属性,这里就重复了。

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