寄生组合式继承是javascript最理想的继承模式,它通过supertype.call(this)继承实例属性、object.create(supertype.prototype)继承原型方法,避免父类构造函数调用两次,确保属性独立与方法复用。

寄生组合式继承是 JavaScript 中最理想的继承模式,它解决了组合继承中父类构造函数被调用两次的问题,既复用了原型上的方法,又保证了实例属性的独立性。
核心思路就两点:
- 用
SuperType.call(this, ...)借用构造函数,继承实例属性(避免引用类型共享); - 用
Object.create(SuperType.prototype)创建父类原型的副本,再挂到子类原型上,继承共享方法(不执行父类构造函数,不污染子类原型)。
手动实现步骤
-
定义父类(含实例属性和原型方法)
function SuperType(name) { this.name = name; this.colors = ['red', 'blue']; } SuperType.prototype.sayName = function() { console.log(this.name); }; -
定义子类构造函数,并借用父类构造函数初始化实例属性
function SubType(name, age) { SuperType.call(this, name); // 只在这里调用一次,拿到自己的 name/colors this.age = age; } -
手动设置子类原型 = 父类原型的干净副本(关键!)
// 创建父类原型的副本(不含父类实例属性) const prototypeCopy = Object.create(SuperType.prototype); // 修复 constructor 指向 prototypeCopy.constructor = SubType; // 替换子类原型 SubType.prototype = prototypeCopy;
-
在子类原型上添加自有方法(可选)
SubType.prototype.sayAge = function() { console.log(this.age); };
为什么这样写更优?
-
Object.create(SuperType.prototype)不会执行SuperType构造函数,所以子类原型上没有多余的name、colors实例属性; - 子类实例通过
SuperType.call(this)各自拥有独立的colors数组,不会相互影响; - 方法全部从
SuperType.prototype原型链继承,复用高效; -
constructor被显式修正,new SubType().__proto__.constructor === SubType成立。
常见错误点提醒
- ❌ 直接
SubType.prototype = SuperType.prototype:子类原型和父类原型引用同一对象,修改会互相影响; - ❌
SubType.prototype = new SuperType():触发父类构造函数,导致原型上出现无意义的实例属性; - ❌ 忘记
prototype.constructor = SubType:instance.constructor会指向SuperType,造成混淆; - ❌ 在
SubType.prototype = ...之后再添加方法:必须在赋值之后添加,否则会被覆盖。
不复杂但容易忽略细节。











