组合继承是javascript最常用继承模式,融合原型链与借用构造函数优点:子类构造函数中调用parent.call(this)确保实例属性独立,child.prototype = new parent()实现方法复用,并需修复constructor指向。

组合继承是 JavaScript 中最常用、也最被推荐的手动实现继承的方式,它把构造函数继承和原型链继承的优点结合起来,同时规避了二者单独使用时的关键缺陷。
为什么需要组合继承
单独用原型链继承,会导致所有子类实例共享父类的引用类型属性(比如数组、对象),而且无法向父类构造函数传参;只用构造函数继承,虽然能避免共享问题、支持传参,但子类拿不到父类原型上的方法,造成方法无法复用、每个实例都重复创建函数,浪费内存。组合继承正是为了解决这两个矛盾而设计的。
核心思路:分层继承
它把继承任务拆开处理:
-
属性继承靠构造函数:在子类构造函数中用
Parent.call(this, ...args)调用父类,让每个子类实例拥有自己独立的父类实例属性(包括基本类型和引用类型); -
方法继承靠原型链:把父类的原型对象整体赋给子类原型(
Child.prototype = new Parent()或更优地用空函数中转),使子类实例能通过原型链访问父类定义在prototype上的方法,实现函数复用。
典型写法与关键细节
标准实现通常包含三步:
- 定义父类构造函数,并在其
prototype上挂载共用方法; - 子类构造函数内部调用
Parent.call(this, ...),初始化自身属性; - 设置
Child.prototype = Object.create(Parent.prototype)(或new Parent()),再手动修复constructor指向子类。
注意:若直接用 new Parent() 设置子类原型,会执行一次父类构造函数——这虽无副作用(因属性已在子类构造中初始化),但属于冗余调用;用 Object.create(Parent.prototype) 更精准,避免不必要执行。
它解决了什么,又留下什么
✅ 成功避开原型链的共享问题和传参限制;
✅ 保留了原型方法的复用性,不重复创建函数;
❌ 但父类构造函数仍被调用了两次:一次在子类构造中(call),另一次在设置原型时(new Parent())。这个小瑕疵正是寄生组合式继承后续要优化的点,不过对多数场景影响不大。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











