typeerror: super.xxx is not a function 是因父类未定义该方法;super 仅代理父类原型上的同名属性,不兜底、不继承,需确认父类存在该方法、拼写正确、非私有且已初始化。

super 调用父类方法时,为什么报错 TypeError: super.XXX is not a function
常见于子类方法里写了 super.methodName(),但运行时报这个错——不是语法问题,而是父类里根本没定义那个方法。JavaScript 的 super 不会“自动继承”或“兜底”,它只代理当前原型链上紧邻父类的同名属性。
实操建议:
- 先确认父类(
class A)确实导出了该方法,且不是私有字段(#method)或未初始化的 getter - 检查是否拼写错误,比如父类是
init(),子类却写成super.initialize() - 若父类方法是异步的,确保调用时用了
await,否则可能返回undefined被误判为非函数 - 在构造器中调用
super()之前,不能访问this,否则直接报ReferenceError,这和方法调用错误无关但常被混淆
super() 必须在 constructor 中第一行调用?为什么不能延迟或包裹在 if 里
必须。ES6 class 规范强制要求:只要子类写了 constructor,就必须显式调用 super(),且只能在 this 访问前、且仅一次。
实操建议:
-
super()不只是“调用父构造器”,它负责初始化this绑定;不调或晚调,this就是未定义状态 - 不能放进条件分支里,比如
if (x) { super(); }—— 解析时就报ReferenceError: Must call super constructor in derived class before accessing 'this' - 如果需要条件逻辑,把判断放在
super()之后,或提前计算好参数再传入super(arg1, arg2)
super 访问父类属性时,this.xxx 和 super.xxx 行为差异在哪
关键区别在于查找路径:this.xxx 沿整个原型链向上找(含自身、父类、祖父类),而 super.xxx 只查父类的定义(即 Object.getPrototypeOf(this.constructor.prototype) 上的属性)。
实操建议:
- 当父类和子类都定义了同名属性(如
name),this.name返回子类值,super.name强制读父类值 -
super.xxx不能用于赋值普通属性(如super.name = 'a'会静默失败或报错),仅适用于方法调用、getter/setter 或构造器 - 若父类用
Object.defineProperty定义了不可写属性,super.xxx读取正常,但通过this.xxx赋值会失败(取决于属性配置)
TypeScript 中 super 的类型检查为何有时“放水”有时报错
TypeScript 在编译期模拟 JS 运行时行为,但对 super 的类型推导依赖声明——如果父类类型不完整(比如用 any 或缺失 declare),TS 就无法校验 super.xxx 是否存在。
实操建议:
- 确保父类是明确的 class 声明(而非
interface或type),TS 才能绑定super类型 - 避免在泛型父类中过度依赖
super调用,尤其当泛型参数影响方法签名时,容易出现Property 'xxx' does not exist on type 'typeof SuperClass' - 开启
noImplicitAny和strict,能让 TS 更早暴露super调用缺失定义的问题
真正容易被忽略的是:super 不是“父类实例”,它只是一个语法绑定,背后没有独立对象;所有 super.xxx 都作用于当前 this 实例。一旦忘了这点,就会在重写 setter 或修改原型时踩坑。








