SyntaxError: functions cannot be labelled

函式 宣告前帶有一個 標籤 時,會發生 JavaScript 異常 "函式不能被標記"。

訊息

SyntaxError: In non-strict mode code, functions can only be declared at top level, inside a block, or as the body of an if statement. (V8-based)
SyntaxError: In strict mode code, functions can only be declared at top level or inside a block. (V8-based)
SyntaxError: Generators can only be declared at the top level or inside a block. (V8-based)
SyntaxError: Async functions can only be declared at the top level or inside a block. (V8-based)

SyntaxError: functions can only be labelled inside blocks (Firefox)
SyntaxError: functions cannot be labelled (Firefox)
SyntaxError: generator functions cannot be labelled (Firefox)
SyntaxError: async function declarations can't appear in single-statement context (Firefox)

SyntaxError: Unexpected keyword 'function'. Function declarations are only allowed inside block statements or at the top level of a program. (Safari)
SyntaxError: Function declarations are only allowed inside blocks or switch statements in strict mode. (Safari)
SyntaxError: Unexpected token '*'. Cannot use generator function declaration in single-statement context. (Safari)
SyntaxError: Unexpected keyword 'function'. Cannot use async function declaration in single-statement context. (Safari)

錯誤型別

SyntaxError

哪裡出錯了?

函式宣告不應該被標記,因為標籤只應該應用於語句,而不是宣告。實際上無法跳轉到這個標籤。然而,由於一些遺留的 JavaScript 語法規則,錯誤條件比必要情況稍微複雜一些。

  • 嚴格模式 中,函式宣告絕不允許被標記。
  • 在非嚴格模式下,函式宣告允許被標記,但當該函式是 if 語句的唯一語句時(這本身是一個已廢棄的特性)除外。
  • 非同步函式、生成器函式和非同步生成器函式絕不允許被標記。

錯誤訊息可能會說類似“函式宣告出現位置無效”的話,因為當解析器看到標籤時,它期望後面跟著一個語句,而函式宣告不是一個語句。這取決於錯誤的視角是標籤不能後跟函式,還是函式不能前跟標籤。

示例

錯誤的解析物件字面量

雖然你可能確實希望這個標籤能做一些類似跳轉目標的事情,但通常你並不打算讓它成為一個標籤。最常見的情況是你實際上希望它成為物件字面量中的一個屬性鍵。

js
const createObj = () => {
  greet: function greet() { // SyntaxError: functions cannot be labelled
    console.log("Hello");
  }
};

在這裡,{...} 實際上不是一個物件字面量,而是 箭頭函式 的塊體,所以 greet: 成為了一個標籤。要解決這個問題,你需要將物件字面量用括號括起來。

js
const createObj = () => ({
  greet: function greet() {
    console.log("Hello");
  },
});

你可能還想在物件字面量中使用 方法語法,這樣可以避免這個陷阱。

js
const createObj = () => ({
  greet() {
    console.log("Hello");
  },
});

另見