组合继承是javascript最常用继承方式,它结合构造函数继承(确保实例属性独立、支持传参)和原型链继承(复用原型方法、需修复constructor),但父类构造函数会被调用两次,可能引发副作用。

组合继承是 JavaScript 中最常用、也最贴近“传统面向对象”直觉的继承方式,它把构造函数继承(解决实例属性私有化)和原型链继承(复用原型方法)两个优点结合起来,既避免了引用类型共享问题,又能让子类实例访问父类原型上的方法。
构造函数继承:确保每个实例拥有独立的属性
在子类构造函数内部,用 call() 或 apply() 调用父类构造函数,把父类的实例属性复制到当前 this 上:
- 这样每个子类实例都有一份自己的
name、colors等属性,互不干扰 - 支持向父类传参,比如
SuperType.call(this, name) - 但无法访问父类原型上的方法(如
sayName),因为没建立原型关系
原型链继承:让所有实例共享原型方法
把子类的 prototype 指向父类的一个实例,从而让子类原型链上能查找到父类原型的方法:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 写法是
SubType.prototype = new SuperType() - 之后子类实例调用
sayName()就能沿原型链找到 - 必须紧接着修复
constructor指向:SubType.prototype.constructor = SubType,否则会指向SuperType
组合起来的关键顺序不能错
先完成构造函数继承(在子类构造函数里),再设置原型链(在构造函数外部),整个流程才完整:
- 子类构造函数中调用
SuperType.call(this, ...)→ 获取独立实例属性 - 子类
prototype赋值为new SuperType()→ 接入父类原型方法 - 手动修正
SubType.prototype.constructor→ 保持构造器信息准确 - 子类自己新增的方法,要加在
SubType.prototype上,且必须在原型赋值之后
注意它的典型缺陷
组合继承虽然实用,但有个小瑕疵:父类构造函数会被调用两次:
- 一次在子类构造函数中(
SuperType.call(...)),用于初始化实例属性 - 另一次在
new SuperType()创建子类原型时,只为挂载原型链,实际并不需要执行构造逻辑
这个重复调用在多数场景影响不大,但若父类构造函数有副作用(比如发请求、改状态),就值得警惕。进阶方案如寄生组合继承,正是为消除这第二次调用而设计的。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










