寄生组合式继承优于组合继承,因父类构造函数仅执行一次。组合继承因原型链继承和构造函数继承双重调用导致属性重复;寄生组合式继承通过Object.create等方法复用原型,避免冗余属性与内存浪费。

本质区别在于父类构造函数是否被调用两次——组合继承会执行两次,寄生组合式继承只执行一次。
组合继承:两次调用父构造函数
它把构造函数继承(Parent.call(this, ...))和原型链继承(Child.prototype = new Parent())拼在一起用。问题就出在后一步:new Parent() 会实实在在执行一遍父类构造函数,给子类原型上挂一份实例属性(比如 this.name、this.colors);而子类实例创建时,又在构造函数里再 call 一次。结果就是:同一份实例属性在原型和实例上各存一份,浪费内存,还可能引发引用类型共享问题。
- 子类实例有自己的一套
name和colors - 子类原型上也有另一套(由
new Parent()生成) - 修改实例的
colors不影响其他实例,但原型上的那份始终存在、不参与实际使用
寄生组合式继承:只调用一次,精准复用原型
它绕开了 new Parent() 这个动作,改用更轻量的方式“复制”父类的原型对象——比如 Object.create(Parent.prototype) 或自定义的 object() 函数。这样得到的新对象,原型链正确指向 Parent.prototype,但本身不含父类构造函数执行产生的实例属性。
- 父类构造函数仅在子类实例化时调用一次(
Parent.call(this, ...)) - 子类原型干净,只继承方法,不带冗余属性
- 避免了属性重复、内存浪费,也消除了原型上意外携带数据的风险
怎么选?看场景和兼容性要求
现代项目优先用寄生组合式继承,尤其是需要严谨继承语义或处理引用类型属性(如数组、对象)时。它的逻辑更清晰、行为更可预测。
- 支持 ES5+:直接用
Object.create(Parent.prototype),简洁可靠 - 需兼容老浏览器(如 IE8):用封装好的
inheritPrototype(Child, Parent)辅助函数 - 只是简单继承、无引用属性、代码量少:组合继承够用,理解成本低
- 用 class 语法(ES6+):底层已自动实现类似寄生组合式的效果,无需手动处理
不复杂但容易忽略

















