super在静态方法中指向父类构造函数,用于静态调用;在实例方法中指向父类原型,依赖this绑定实例。二者语义、绑定对象及使用限制均不同,不可混用。

super 在静态方法和实例方法中根本不能共用同一套理解逻辑——它在两类方法里的语义、绑定对象和使用限制都完全不同。关键不是“指向谁”,而是“它能指向谁”以及“为什么只能那样指向”。
实例方法中的 super:指向父类原型对象
在普通实例方法里,super 是一个语法标识,用于访问父类原型(Parent.prototype)上的方法或属性。
- 调用
super.method()时,JS 引擎从父类的原型链上查找该方法,等价于Parent.prototype.method.call(this) - 它依赖
this的存在,因为最终方法执行仍需绑定当前实例(this) - 不能访问父类实例上动态添加的属性(比如构造函数里用
this.x = ...定义的),只认定义在prototype上的成员
静态方法中的 super:指向父类构造函数本身
在 static 方法中,super 不再关联原型,而是直接指向父类的**类对象(即构造函数)**。
- 调用
super.staticMethod(),等价于Parent.staticMethod() - 此时不涉及
this,也不需要实例,纯粹是类层级的静态调用 - 可用于继承链中复用父类的静态逻辑,比如工厂方法、常量获取、工具函数等
为什么静态方法里不能用 this,却能用 super?
这不是矛盾,而是设计分工:
-
this在静态方法中无意义——它本就代表“当前实例”,而静态方法不依附于任何实例 -
super在静态方法中也不是“指向父实例”,而是编译期确定的父类引用,属于类结构的一部分,和Parent字面量地位相当 - 引擎通过
[[HomeObject]]内部槽,在定义方法时就锁定了super所属的父类,与运行时有没有实例无关
两个典型错误场景帮你确认理解是否到位
以下写法会直接报错,暴露常见混淆点:
-
class B extends A { static m() { console.log(super.x); } }→ 若A.x是实例属性(非静态),这里会undefined,因为super在静态方法中不访问实例部分 -
class B extends A { m() { super.constructor(); } }→ 错误!super.constructor是函数引用,但不能这样直接调用;正确写法是构造器首行用super() - 在箭头函数里写
super.xxx→ 报错!箭头函数没有自己的super绑定,它不构成方法上下文

















