原型继承本身不直接支持子类调用父类构造函数,因其仅负责方法和属性的委托查找;真正实现需组合继承等方案,在子类构造函数中用call/apply显式调用父类构造函数并配合Object.create设置原型链。

原型继承本身不直接支持子类调用父类构造函数——因为原型链只负责方法和属性的委托查找,构造函数调用是独立行为。真正实现“子类调用父类构造函数”的,是组合继承或寄生组合继承这类混合方案,它们在原型链基础上,额外在子类构造函数中显式调用父类构造函数。
为什么原型链继承做不到这点?
原型链继承(如 Child.prototype = new Parent())是在设置子类原型时,一次性执行父类构造函数,生成一个共享实例。这个执行发生在子类定义阶段,而非每个子实例创建时;而且无法传参,也无法绑定到当前子实例的 this 上。所以它只是“继承了父类实例的初始状态”,不是“每次新建子类实例时调用父类构造逻辑”。
正确做法:在子类构造函数中用 call/apply 调用父类构造函数
这是解决属性初始化、避免引用共享、支持传参的关键步骤:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 在子类构造函数内部,用
Parent.call(this, ...args)或Parent.apply(this, args) - 这样能确保每个子实例都拥有自己独立的属性副本(比如数组、对象),不会互相影响
- 可向父类传递参数,实现定制化初始化
同时保留原型方法继承:用 Object.create 设置原型链
仅靠构造函数调用只能继承实例属性,无法复用父类原型上的方法。必须配合原型链设置:
立即学习“Java免费学习笔记(深入)”;
- 用
Child.prototype = Object.create(Parent.prototype)建立委托关系 - 手动修复构造器:
Child.prototype.constructor = Child - 之后子类实例既能访问父类原型方法(如
parentMethod()),又能拥有各自独立的实例属性
ES6 class 是更简洁的等价写法
class 语法底层仍是原型继承,但把上述两步封装得更清晰:
- 子类构造函数中必须显式调用
super(...args)—— 这本质就是Parent.call(this, ...args) -
extends关键字自动处理原型链:Child.prototype.__proto__ === Parent.prototype - 无需手动操作
Object.create或修复constructor

















