多级子类调用 super 的执行顺序是 Parent → Child → GrandChild;构造调用链自下而上(GrandChild→Child→Parent),但实际执行流向自上而下,每层 super() 为上一层 this 初始化,且 super() 必须首行调用、仅一次、不可用 call 替代。

多级子类调用 super 的执行顺序,本质是沿着原型链向上逐层触发父类构造函数,且每层都必须在使用 this 前调用 super() —— 这不是可选逻辑,而是 JavaScript 引擎强制的初始化链条。
构造调用链严格自下而上,但执行流向自上而下
当你写 new GrandChild(),引擎实际按以下顺序执行:
- 先进入
GrandChild.constructor,但立刻被阻塞:未调用super()前禁止访问this - 于是跳转执行
Child.constructor(因为GrandChild extends Child) -
Child.constructor同样被阻塞,继续向上跳转到Parent.constructor -
Parent.constructor执行完毕,返回;Child.constructor接着执行剩余语句(如赋值this.xxx);最后GrandChild.constructor才得以继续
也就是说:调用栈是 GrandChild → Child → Parent,但实际执行顺序是 Parent → Child → GrandChild。每一层的 super() 都是在为“上一层的 this”完成初始化铺路。
super() 不是“跳过去”,而是“委托并等待返回”
super(...args) 在子类构造器中不是简单跳转,而是等价于:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 以当前正在构建的实例(即未来
this)为this,调用父类构造函数 - 父类构造函数内部对这个
this添加属性、执行逻辑 - 父类构造函数返回后,子类才被允许继续操作同一个
this
例如:class A { constructor(x) { this.a = x; } },class B extends A { constructor(x, y) { super(x); this.b = y; } },class C extends B { constructor(x, y, z) { super(x, y); this.c = z; } }。
执行 new C(1,2,3) 后,实例上最终有 a:1、b:2、c:3 —— 属性是分三阶段、由三类构造器分别挂载的,不是一次性拷贝。
方法中 super.xxx() 是静态绑定,不参与构造链
这和构造器里的 super() 完全不同:
- 在实例方法里写
super.run(),只表示“调用定义在[[Prototype]]上的run方法”,不触发任何构造流程 - 它不改变
this指向,this仍是当前子类实例,只是方法体来自父类原型 - 即使在
C.prototype.walk中写super.walk(),也只会查到B.prototype.walk或A.prototype.walk,不会“跨两级自动找最顶父类”——它只查直接父类原型
不能跳过中间层,也不能绕开 super()
ES6 明确禁止以下写法:
-
class C extends B { constructor() { A.call(this); } }—— 错误:必须用super(),不能用.call() -
class C extends B { constructor() { super(); super(); } }—— 错误:super()只能调用一次,且必须是首条语句 -
class C extends B { constructor() { this.x = 1; super(); } }—— 错误:this使用在super()前,报ReferenceError
这种限制确保了原型链上每层初始化的可控性与顺序性,避免属性覆盖错乱或 this 状态不一致。

















