425 字
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(); // wenginstance1.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);
组合继承的问题
看以上的组合继承代码,你会发现这里的超类也就是SuperType被实例化了两次
- 在SubType将其原型覆盖为SuperType构造函数new出来的实例的时候
- 在SubType构造函数创建实例的时候,构造函数内部直接调用了SuperType,这里又初始化了一次
造成的问题就是,SuperType创建出来的实例,也就是此时SubType的原型,会带有SuperType构造函数初始化的参数,并且,SubType构造函数创建出来的实例,也会带着SuperType的属性,这里就重复了。