寄生组合继承是目前javascript中最接近“最优解”的原型继承方式,它通过object.create(parent.prototype)避免父构造函数重复调用,解决引用属性共享与方法不可继承问题,并需手动修复constructor指向。

寄生组合继承是目前 JavaScript 中最接近“最优解”的原型继承方式,它解决了原型链继承的引用属性共享问题,也规避了组合继承中父构造函数被重复调用的缺陷。
为什么寄生组合继承更优
原型链继承会让所有子实例共享父类的引用类型属性(比如数组、对象);借用构造函数继承虽能隔离实例属性,却无法继承父类原型上的方法。组合继承把两者拼在一起,但父类构造函数会被执行两次——一次在设置子类原型时,一次在子类实例化时。寄生组合继承用 Object.create(Parent.prototype) 替代 new Parent(),让子类原型直接关联父类原型,不再触发父构造函数,从而只调用一次。
核心实现步骤
- 用 call 在子类构造函数中调用父类构造函数,确保实例属性正确初始化(如
this.name = name) - 用 Object.create(Parent.prototype) 设置子类原型,避免执行父类构造逻辑
- 手动修复 constructor 指向,保证
Child.prototype.constructor === Child - 在子类原型上添加自有方法,不影响父类原型结构
一个简洁可用的写法
以父类 Animal 和子类 Dog 为例:
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() { console.log(this.name + ' makes a sound'); };
function Dog(name, breed) {
Animal.call(this, name); // 实例属性继承
this.breed = breed;
}
// 关键:不 new Animal(),而是继承其原型
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.bark = function() { console.log(this.name + ' barks'); };
ES6 class 与寄生组合继承的关系
class 和 extends 是语法糖,底层依然走的是寄生组合继承的逻辑路径。编译后代码会自动完成 Object.create(Parent.prototype)、constructor 修正、以及 super() 对应的 Parent.call(this)。开发中推荐用 class,但理解寄生组合继承有助于调试原型链、排查 instanceof 或方法丢失等问题。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











