子类构造函数中必须首行调用 super(),否则触发 ReferenceError;不写 constructor 最安全,写了则必须显式、同步、首行调用 super(),且不可异步或条件调用,ESLint 和 TypeScript 可静态拦截。

直接在子类构造函数中访问 this 前不调用 super(),会立刻触发 ReferenceError,程序中断、实例无法创建。这不是逻辑 bug,而是 JavaScript 强制执行的初始化约束。防范的关键不是“绕过”,而是建立清晰、可落地的编码习惯和检查机制。
明确构造函数的准入门槛
只要子类显式声明了 constructor,就必须手动处理父类初始化——super() 是唯一入口,且不可省略、不可延迟。
- 不写
constructor最安全:引擎自动注入constructor(...args) { super(...args); },零风险 - 写了
constructor就等于主动接管初始化流程,必须首行调用super() - 哪怕父类构造函数为空、子类也不设任何属性,仍需写
super()
严格遵守 super() 的位置规则
super() 必须是构造函数中第一个可执行语句。注释、let/const 声明(无赋值)可以前置,但任何实际操作都不行。
- ✅ 正确:
constructor() { super(); this.name = 'x'; } - ❌ 错误:
constructor() { this.name = 'x'; super(); }(this访问在前) - ❌ 错误:
constructor() { return; super(); }(return提前终止) - ❌ 错误:
constructor() { if (true) super(); }(条件分支,引擎静态拒绝)
用工具提前拦截问题
这类错误在运行时才暴露,但完全可以被静态检查捕获。
- 启用 ESLint 规则
constructor-super(默认开启),它会在编译/保存阶段报错 - TypeScript 编译器同样强制校验,未调用
super()直接编译失败 - 编辑器(如 VS Code)配合插件,能实时高亮违规写法,避免手滑
异步初始化不要塞进构造函数
构造函数必须同步完成。若需异步数据(如 API 获取配置),不能把 super() 推迟到 await 后——这语法非法,也违背设计初衷。
- ✅ 正确做法:用工厂函数封装异步逻辑,再同步调用
new Child(data) - ✅ 或者:构造函数只做最小初始化(
super()+ 必要字段),后续用init()方法异步加载 - ❌ 禁止:
async constructor()(语法错误)、await fetch().then(() => super())(super()不可异步)

















