javascript继承中构造函数不会自动调用父类,必须显式使用super()或parent.call(this);es6 class要求super()在访问this前调用,否则报错;原型链仅影响方法查找,不保证实例属性初始化。

JavaScript 中继承链的构造函数调用顺序,取决于你使用的继承方式(原型链、ES6 class、寄生组合式等)以及是否显式调用父类构造函数。核心原则是:子类构造函数不会自动执行父类构造函数,必须手动调用 super() 或 Parent.call(this);调用位置决定初始化时机,而原型链的建立则影响方法查找路径。
ES6 class 中的 super() 调用顺序
使用 class 语法时,子类构造函数中必须在访问 this 前调用 super(),否则会报错。该调用会触发父类构造函数执行,且按继承层级从上到下依次进行。
- 父类构造函数先执行,完成父类实例属性初始化
- 然后子类构造函数继续执行,添加或覆盖自身属性
- 若未写
super(),JS 引擎直接抛出ReferenceError -
super()实质是调用父类 constructor,并绑定当前this
原型链继承中的手动 call/apply 调用
在传统原型链 + 构造函数借用模式中(如 Child.prototype = Object.create(Parent.prototype)),父类构造函数不会自动运行,需在子类构造函数内部显式调用 Parent.call(this, ...)。
- 调用位置决定了属性挂载顺序:写在前面,父类属性先存在;写在后面,可能被子类同名属性覆盖
- 不调用
Parent.call(this),实例将缺少父类定义的this.xxx属性(但可通过原型访问方法) - 多个父类继承时(如多重继承模拟),可多次调用不同构造函数,顺序由代码书写顺序决定
继承链与原型链的分离关系
构造函数调用顺序和原型链查找顺序是两件事:前者控制 this 上的属性初始化过程,后者控制方法和属性的动态查找路径(沿着 __proto__ 向上)。
- 即使没调用
super()或Parent.call(this),只要原型链正确设置,仍能访问父类原型上的方法 - 但父类构造函数中赋值给
this的实例属性(如this.name = name)不会出现,除非手动调用 - 错误地只设原型不调构造函数,常导致“属性 undefined”问题,容易误判为继承失败
常见陷阱与验证方式
判断构造函数是否被正确调用,不能只看方法能否访问,而要看实例自身属性是否存在。可用 Object.getOwnPropertyNames(obj) 或 hasOwnProperty 检查。
- 忘记
super()→ SyntaxError(class 场景) -
super()写在this使用之后 → ReferenceError - 原型继承中漏掉
Parent.call(this)→ 实例缺少父类 this 属性,但原型方法仍可用 - 子类重写父类方法后,在
super.method()中调用的是父类版本,而非当前实例的重写版
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











