寄生组合式继承是JavaScript最推荐的继承模式,它通过Object.create(Super.prototype)避免父类构造函数被调用两次,既保证实例属性隔离,又完整继承原型方法,兼具性能与正确性。

寄生组合式继承是 JavaScript 中最推荐的继承模式,它解决了经典组合继承中父类构造函数被调用两次的问题,同时完整保留原型链关系和实例属性隔离。核心在于:**只调用一次父类构造函数(用于子类实例初始化),且不执行父类构造函数来设置子类原型**。
为什么经典组合继承要调用父类构造函数两次?
典型写法如下:
-
第一次调用:在子类构造函数内部用
Super.call(this)初始化实例属性 -
第二次调用:通过
Sub.prototype = new Super()设置原型,此时会再次执行Super构造函数,把本该属于实例的属性(如this.name、this.colors)挂到Sub.prototype上,造成冗余和潜在数据污染
寄生组合式继承的关键三步
目标是让 Sub.prototype 继承 Super.prototype 的方法,但不触发 Super 构造逻辑。做法是:
- 用
Object.create(Super.prototype)创建一个空对象,其__proto__直接指向Super.prototype - 手动把该对象的
constructor指回Sub,避免原型链断裂 - 将
Sub.prototype指向这个新对象,完成原型链桥接
标准封装与使用示例
通常封装为复用函数:
立即学习“Java免费学习笔记(深入)”;
function inheritPrototype(Child, Parent) {
const prototype = Object.create(Parent.prototype);
prototype.constructor = Child;
Child.prototype = prototype;
}
function Super(name) {
this.name = name;
this.colors = ['red', 'blue'];
}
Super.prototype.sayName = function() { console.log(this.name); };
function Sub(name, age) {
Super.call(this, name); // 只在这里调用 Super
this.age = age;
}
inheritPrototype(Sub, Super); // 不再 new Super()
Sub.prototype.sayAge = function() { console.log(this.age); };
const s1 = new Sub('Alice', 30);
s1.sayName(); // "Alice"
s1.sayAge(); // 30
console.log(s1 instanceof Super); // true
它比其他方式强在哪?
对比常见方案:
- 比原型链继承:避免引用类型属性共享(如
colors被多个实例误改) - 比盗用构造函数:能继承父类原型方法,支持方法复用和
instanceof判断 - 比经典组合继承:消除一次无意义的父类构造调用,原型干净、内存高效


















