Skip to content

组合继承 ​

本节目标:理解“组合继承”的核心思路,并能把它用于实际开发或面试表达。 组合继承(combination inheritance),有时候也叫做伪经典继承,指的是将原型链和借用构造函数的技术组合到一块,从而发挥二者之长的一种继承方式。

==这是最常用的继承模式。而且,==instanceof==和==isPrototypeOf()==也能够用于识别基于组合继承创建的对象。==

思路:

  • 父类实例非共享的属性,子类实例通过借用父类构造函数来实现;
  • 父类实例中可共享的属性,子类实例通过指定子类构造函数原型为父类实例来实现。

注意:

  • 指定子类特有非共享属性:调用父类构造函数之后再指定子类特有的属性以防覆盖;
  • 指定子类特有共享属性:指定子类构造函数原型之后再指定子类原型上的自有方法,这些方法只供子类实例共享。

如下: function SuperType(name) { this.name = name; this.colors = ['red', 'blue', 'green']; } SurperType.prototype.sayName = function () { console.log(this.name); } function SubType(name, age) { //继承属性 SurperType.call(this, name); this.age = 29; //继承方法 SubType.prototype = new SuperType(); SubType.prototype.sayAge = function () { console.log(this.age); } } var instance1 = new SubType('Nicholas', 29); instance1.colors.push('black'); console.log(instance1.colors);//'red,blue,green,black' instance1.sayName();//'Nicholas' var instance2 = new SubType('Greg', 27); console.log(instance2.colors);//'red,blue,green' instance2.sayName();//'Greg' instance2.sayAge();//27

组合继承的问题:

  • 组合继承无论什么情况下,都会调用两次超类构造函数:一次是在创建子类型原型的时候,另一次是在子类型构造函数内部。
  • 子类在指定子类构造函数原型的时候会继承超类实例的所有实例属性;但在创建子类实例时,又在子类构造函数中调用超类构造函数时,又重新定义了这些属性,这样子类实例自身的同名属性屏蔽了对原型对象上同名属性的访问。看码:

function SuperType(name) { this.name = name; this.colors = ['red', 'blue', 'green'] } SuperType.prototype.sayName = function () { console.log(this.name); } function SubType(name, age) { //第二次调用SuperType() SuperType.call(this,name); this.age = age; } //第一次调用SuperType() SubType.prototype = new SuperType(); SubType.prototype.constructor = SubType; SubType.prototype.sayAge = function () { console.log(this.age); } 在第一次调用SuperType构造函数时,SubType.prototype会得到两个属性:name和colors;它们都是SuperType的实例属性,只不过现在位于SubType的原型中。当调用Subtype构造函数时,又会调用一次SuperType构造函数,这一次又在新对象上创建了实例属性name和colors。于是,这两个属性就屏蔽了原型中的两个同名属性。

本站总访问 — 次