super调用父类构造函数顺序详解

作者:技术拾光

时间:2026-07-26

浏览:527

在JavaScript和TypeScript类继承中,子类构造函数第一行必须调用super()且只能一次,参数需匹配父类构造函数签名。多层继承时每级子类都要调用直接父类的super()。不写构造函数时自动插入super调用。这是类继承的强制性要求,否则会引发错误。

文章目录

在 JavaScript 和 TypeScript 的类继承体系中,super() 的调用规则看似简单,但稍不留神就会踩坑。比如:为什么必须在子类构造函数的第一行调用它?为什么不能省略?参数传递又有哪些讲究?下面这几个要点,就是你要记住的核心。

super调用父类构造函数顺序详解

一句话概括:子类构造函数中,super() 必须出现在开头,且只能调用一次。

super() 必须是第一条语句

只要子类显式定义了 constructor,就必须在第一行调用 super(),否则会直接报错:ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor。这背后的逻辑是:父类的初始化必须先完成,this 对象才能拥有正确的原型链和初始状态。所以,哪怕不需要给父类传任何参数,也必须写一句 super()(空调用)。更严格的是,在 super() 之前,你不能访问 this,也不能写任何其他语句——不管是变量声明、return 还是 if 判断,统统不允许。

参数传递要匹配父类构造函数签名

super(...args) 传入的参数必须与父类 constructor 的形参顺序和类型一致。举个例子:父类是 constructor(name, age),子类就得写 super(name, age)。当然,你可以做一些预处理,比如 super(name.trim(), Math.max(0, age)),但调用本身依然要放在第一行。如果父类构造函数有默认值或可选参数,也记得按需传入,避免意外得到 undefined。

继承链中每级都要调用 super

当出现多层继承(比如 A → B → C),每一级子类的 constructor 都必须调用自己的直接父类的 super()。也就是说,C 类调用 B 的 super(),B 类再调用 A 的 super()。你不能跳过中间层直接调用祖先的构造函数——语法上就不允许。而且每一级的 super() 都同样遵循“第一行”的规则。

不写 constructor 时自动插入 super()

如果子类没有定义 constructor,JavaScript 和 TypeScript 会自动补一个空构造函数,并在其中调用 super(),效果相当于隐式写了 constructor(...args) { super(...args); }。这时候你是无法控制参数传递逻辑的。所以,如果需要自定义初始化(比如处理参数、设置默认值),就必须显式声明 constructor 并手动调用 super。一旦你写了 constructor,隐式行为就失效了,所有 super 调用的责任都得自己扛。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章