ReferenceError: 在派生类构造函数中调用 super() 两次
当对给定的派生类构造函数第二次调用 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)
错误类型
哪里错了?
对于每次对派生类构造函数的 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
}
}