组合继承是JavaScript最常用可靠的继承模式,它结合构造函数继承与原型链继承:通过call/apply实现实例属性独立,避免引用类型共享;通过Object.create(Parent.prototype)实现方法复用;支持传参、兼容性强且调试友好。

组合继承是JavaScript中最常用、最可靠的继承模式,它把构造函数继承和原型链继承的优点结合起来,既保证了实例属性的独立性,又实现了方法的复用。
避免属性重复创建,每个实例拥有独立状态
通过在子类构造函数中调用父类构造函数(call/apply),可以让父类中定义在this上的属性(如字符串、数字、数组、对象等)在每个子类实例上重新初始化。这样就不会出现多个实例共享引用类型属性的问题。
例如:
function Parent(name) {this.name = name;
this.hobbies = ['reading'];
}
function Child(name, age) {
Parent.call(this, name); // 关键:确保 this.hobbies 是新数组
this.age = age;
}
方法复用,不重复占用内存
把公共方法定义在父类原型上,再让子类原型指向父类实例(或使用 Object.create(Parent.prototype)),就能让所有子类实例共享这些方法,避免每次创建实例都生成新函数。
立即学习“Java免费学习笔记(深入)”;
典型写法:
Child.prototype = Object.create(Parent.prototype);Child.prototype.constructor = Child;
Child.prototype.sayHello = function() {
console.log('Hello, I\'m ' + this.name);
};
支持传参,构造逻辑清晰可控
构造函数继承天然支持向父类传递参数,子类初始化时可灵活控制父类状态的构建过程。相比单纯依赖原型链(无法传参给父类构造逻辑),这种方式更符合面向对象中“初始化即定制”的直觉。
- 父类构造函数中的初始化逻辑(如校验、默认值设置)能被完整执行
- 子类可以扩展自己的初始化步骤,与父类解耦
- 调试时容易追踪属性来源——
this.xxx来自构造函数,xxx()来自原型
兼容性强,ES3起就稳定可用
不依赖class、extends或Reflect.construct等新特性,适用于所有主流运行环境。即使在老旧浏览器或严格模式下,只要正确设置constructor,就能保持原型链完整、instanceof准确、开发者工具可调试。
注意两个关键细节:
- 必须重置
Child.prototype.constructor,否则它会指向Parent - 推荐用
Object.create(Parent.prototype)而非new Parent()设置原型,避免执行父类构造函数副作用










