消息
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");
},
});