super是javascript中与原型链深度绑定的语法结构,不创建对象或跳转上下文,而是依据类定义时确立的[[prototype]]关系,在构造器、实例方法和静态方法中分别精准指向父类构造器、父类原型或父类构造函数。

super 关键字不是“调用父类”的简写,而是 JavaScript 继承机制中与原型链深度绑定的语法结构。它不创建新对象,也不跳转执行上下文,而是依托类定义时确立的 [[Prototype]] 关系,在不同场景下精准指向父类构造器或父类原型。
super() 必须首行调用,本质是激活 this
子类 constructor 中若定义了构造函数,就必须第一行写 super()(或 super(args))。这不是风格建议,而是引擎强制规则:
- new 表达式创建的是一个空对象,this 初始未绑定;super() 的作用就是把该空对象作为 this,传入父类 constructor 执行初始化
- super() 执行后,this 才被“激活”,之后才能访问 this.xxx;提前读写会报 ReferenceError: Must call super constructor before accessing 'this'
- 整个过程中,this 始终指向子类实例,不是父类实例;父类 constructor 内部的 this === 当前子类实例
- new.target 始终是子类构造函数,哪怕在父类 constructor 内部也保持不变,这对抽象类校验等逻辑至关重要
super.xxx 在方法中指向父类原型,查找有边界
在子类的普通实例方法(非 static)中,super 不是 this 的代理,也不是任意向上查找的通道,它严格限定在父类的 prototype 上:
- super.getName() 会从 Parent.prototype 开始查找 getName,不会继续沿 Parent.prototype.__proto__ 向上找
- 如果 Parent.prototype 上没有 getName,结果就是 undefined,不会退回到 this.getName 或 Object.prototype.getName
- super.xxx = val 实际等价于 this.xxx = val,赋值目标永远是当前子类实例,不会修改父类原型
- 箭头函数中禁止使用 super,因为它没有自己的词法环境,无法解析 super 绑定
静态方法里的 super 指向父类构造函数本身
在子类的 static 方法中,super 的语义完全不同:
- super.create() 查找的是 Parent.create,即父类自身的静态成员,而非 Parent.prototype 上的方法
- 这依赖于类定义时建立的 [[HomeObject]] 和 [[Prototype]] 链:子类构造函数的 [[Prototype]] 指向父类构造函数,所以 super 在静态上下文中自然指向父类
- 这种设计让静态继承保持与实例继承对称,但作用域完全分离——静态方法无法通过 super 访问实例方法,反之亦然
super 与原型链的关系不是隐式穿越,而是显式锚定
JavaScript 引擎在解析 class 时就确定了 super 的目标位置,它不依赖运行时动态查找:
- 子类 class B extends A {} 定义后,B.prototype.[[Prototype]] 被设为 A.prototype;同时 B.[[Prototype]] 被设为 A
- super() 调用的就是 A.prototype.constructor;super.method() 查找起点就是 A.prototype;static 中的 super.xxx 查找起点就是 A
- 这和 this.xxx 的原型链查找(逐级向上直到 Object.prototype)有根本区别:super 是单层、确定、不可绕过的“跳转”,不是“搜索”
- 因此,即使你在 A.prototype 上删掉某个方法,super.xxx 就立刻失效;而 this.xxx 可能还能从更上层找到同名方法
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











