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
  }
}

另見