ReferenceError: super() called twice in derived class constructor
当 super() 在给定的派生类构造函数中第二次被调用时,会发生 JavaScript 异常 "super() 在派生类构造函数中被调用两次"。
消息
ReferenceError: Super constructor may only be called once (V8-based) ReferenceError: super() called twice in derived class constructor (Firefox) ReferenceError: 'super()' can't be called more than once in a constructor. (Safari)
错误类型
ReferenceError
哪里出错了?
对于派生类构造函数的每次 new 调用,super() 最多只能调用一次。这是因为 super() 负责初始化父类,多次调用会导致父构造函数被多次调用。
防止这种情况的最佳方法是确保 super() 放置在任何控制流结构之外。否则,请确保构造函数中的所有代码路径都只导致一次 super() 调用。
super() 调用可以“保存”在构造函数内部嵌套的箭头函数中。然后,当你调用箭头函数时,你也将调用 super(),并且适用相同的规则:箭头函数最多只能被调用一次。
示例
无效案例
js
class Base {}
class Derived extends Base {
constructor() {
super();
super();
}
}
有时错误可能更隐蔽。
js
class Base {
constructor(flavor) {
// Do something with the flavor
}
}
class Derived extends Base {
constructor(flavors) {
if (flavors.includes("chocolate")) {
super("chocolate");
}
if (flavors.includes("vanilla")) {
super("vanilla");
}
}
}
最初,flavors 可能永远不会同时包含“chocolate”和“vanilla”,但如果发生这种情况,构造函数将调用 super() 两次。你需要重新考虑你的类应该如何构建以避免这个问题。
有效情况
js
class Base {}
class Derived extends Base {
constructor() {
super();
// More initialization logic
}
}