组合继承是javascript最经典继承模式,通过构造函数继承实例属性(保证私有)与原型链继承方法(实现复用)结合;子类构造函数内调用parent.call(this, ...args),原型设为object.create(parent.prototype)并修复constructor。

组合继承是 JavaScript 中最经典、最实用的继承模式,它把构造函数继承和原型链继承的优点“拼”在一起:用构造函数继承实例属性(保证每个实例独有),用原型链继承方法(实现函数复用)。关键在于两步不漏、顺序合理。
怎么让子类拥有独立的实例属性?
在子类构造函数内部,用 call() 显式调用父类构造函数,并传入当前 this 和必要参数。这样每次创建子类实例时,都会执行一次父类构造逻辑,生成属于自己的属性副本。
- 比如父类有
this.colors = ['red'],子类实例就不会互相污染数组 - 能正常接收初始化参数,如
new SubType('Alice', 25) - 但注意:这一步只处理实例属性,父类原型上的方法还不会被继承
怎么让子类复用父类的方法?
把子类的 prototype 设置为父类原型的一个干净副本,通常用 Object.create(Parent.prototype)。这避免了直接 new Parent() 带来的副作用(比如执行父类构造函数、引入冗余实例属性)。
- 设置后,子类实例就能通过原型链访问
Parent.prototype上的所有方法 - 必须手动修复
constructor指针:SubType.prototype.constructor = SubType,否则instance.constructor会指向Parent - 不能写成
SubType.prototype = Parent.prototype,那会导致修改子类原型也影响父类
为什么组合继承比单独用某一种更可靠?
单用原型链继承,引用类型属性会被所有实例共享;单用构造函数继承,又拿不到父类原型方法,instanceof 判定也会失效。组合继承补全了这两块短板:
- 实例属性私有化,方法集中复用,内存和逻辑都更合理
-
child instanceof Parent和child instanceof SubType都返回 true - ES6 的
class和extends底层正是基于这种思想实现的
实际写法要注意什么?
组合继承的标准写法有固定结构,漏掉任何一环都可能出问题:
- 子类构造函数里必须调用
Parent.call(this, ...args) - 子类原型赋值必须在构造函数定义之后、实例化之前完成
-
Object.create(Parent.prototype)是推荐方式,比new Parent()更干净 - 别忘了修复
constructor,这是调试和类型识别的关键
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











