语法错误:函数不能加标签

function 声明在其前面有一个 标签 时,就会发生 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)

错误类型

哪里出错了?

函数声明永远不应该加标签,因为标签应该只应用于语句,而不是声明。无法实际跳转到此标签。但是,由于某些旧版 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");
  },
});

另请参阅