寄生组合继承的核心目标是只调用一次父类构造函数并保留原型链关系,通过Object.create(Parent.prototype)搭建原型链避免重复执行,ES6 class是其语法糖。

寄生组合继承的核心目标就是只调用一次父类构造函数,同时完整保留原型链关系。它通过绕开 new Parent() 这一动作,改用 Object.create(Parent.prototype) 来搭建原型链,从而彻底避免重复执行。
为什么经典组合继承会调用两次?
问题出在两处:
- 子类构造函数里调用
Parent.call(this)—— 第一次执行 - 设置原型时写
Child.prototype = new Parent()—— 第二次执行(且创建了无用的实例属性,比如name、like等被挂到原型上)
寄生组合继承的关键操作
只需两个动作,干净解耦构造逻辑和原型继承:
- 用
Object.create(Parent.prototype)创建一个空对象,它的__proto__直接指向Parent.prototype,不触发Parent构造函数 - 手动把新对象的
constructor指回Child,否则会沿原型链指向Parent
标准写法示例
封装一个复用函数更清晰:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
立即学习“Java免费学习笔记(深入)”;
function inherit(Child, Parent) {
const proto = Object.create(Parent.prototype);
proto.constructor = Child;
Child.prototype = proto;
}
function Parent(name) {
this.name = name;
}
Parent.prototype.say = function() {
return this.name;
};
function Child(name, age) {
Parent.call(this, name); // 唯一一次调用
this.age = age;
}
inherit(Child, Parent); // 不再用 new Parent()
此时 new Child('Alice', 25) 中,Parent 只执行一次,Child.prototype 上也没有冗余的 name 属性。
ES6 class 是它的语法糖
你写的 class Child extends Parent,底层就是按上述逻辑自动实现的:原型链正确连接,构造函数只在子类 constructor 中通过 super() 调用一次。不需要手动处理两次调用的问题。

















