super是运行时机制而非语法糖:在实例方法中指向Parent.prototype,静态方法中指向Parent构造函数;super()调用父构造器但this始终绑定子实例;super.x = val实际赋值给this.x。

ES6 的 class 确实是语法糖,但 super 不是——它是一套有明确绑定规则的运行时机制。所谓“调用原型方法”,实际是引擎根据上下文动态解析 super 指向,并严格控制 this 绑定的结果,而非简单地在父类原型上查方法。
super.xxx 在普通方法中,指向 Parent.prototype
当在子类实例方法里写 super.say(),JavaScript 引擎不会去查 this.__proto__.__proto__.say,而是直接定位到父类构造函数的 prototype 对象(即 Parent.prototype)。这个指向是静态确定的,在定义时就由继承关系决定,和当前实例的完整原型链无关。
这意味着:
- 只能访问定义在
Parent.prototype上的方法或 getter/setter,比如Parent.prototype.getName = function(){} - 无法访问父类构造器内挂载的实例属性,如
constructor(){ this.id = 1 }→super.id是undefined - 若
Parent.prototype上没有该属性,返回undefined,不会继续向上查找(区别于this.xxx)
super() 调用父构造器,但 this 始终绑定子实例
super() 出现在子类 constructor 中时,本质是执行 Parent.prototype.constructor.call(this, ...args)。关键点在于:执行的是父类构造逻辑,但整个过程中 this 始终指向正在构建的那个子类实例。
所以:
- 父类构造器里对
this.name的赋值,最终写入的是子实例,不是独立的父实例 - 不调用
super()就访问this,会立即报ReferenceError - 不能在
constructor外部、或非首行位置调用super()
super 在静态方法中,指向 Parent 构造函数本身
静态方法属于类自身,不依赖实例。此时 super.xxx 查找目标变为父类构造函数(Parent),而不是它的原型。例如:
class Parent { static foo() { return 'parent'; } }
class Child extends Parent { static bar() { return super.foo(); } }
Child.bar(); // 'parent'
这说明:
-
super在静态上下文里等价于直接引用父类名,可用于调用父类静态方法或读取静态属性 - 它和实例方法中的
super完全隔离,指向对象不同,不可混用逻辑
赋值操作 super.x = val,实际改的是 this.x
看起来像在操作父原型,其实底层做了转换:super.x = val 等效于 this.x = val。这是为了保证属性写入始终落在当前实例上,避免意外污染父类原型。
验证方式很简单:
- 定义
Parent.prototype.x = 'from proto' - 子类中执行
super.x = 'new value' - 再查
Parent.prototype.x仍是原值,而this.x已更新


















