JavaScript 解释器忽略语法错误

JavaScript interpreter ignores syntax error

这段代码显然有问题:

if (5 > 2) {
  console.log("5 > 2");
} else (5 < 2) {
  console.log("5 < 2");
}

不应指定 else 的条件。执行此代码将导致 SyntaxError: Unexpected token {,正如预期的那样。


问题是在一个小改动之后(将左大括号转移到新行),解释器将简单地忽略语法错误。

此代码:

if (5 > 2) {
  console.log("5 > 2");
} else (5 < 2)
{
  console.log("5 < 2");
}

此输出结果(在 chrome 和 firefox 中测试):

5 > 2
5 < 2

这怎么可能?为什么这个 else 不被视为语法错误?

区别在于,在第二种情况下,回车return使第二个大括号块成为独立块,而不是else子句的一部分,其中括号部分是else子句。第二种情况相当于:

if (5 > 2) {
    console.log("5 > 2");
} else {
    (5 < 2)
}

{
    console.log("5 < 2");
}

这只是:

if (5 > 2) {
    console.log("5 > 2");
} else {
    false
}

console.log("5 < 2");

都是因为Automatic Semicolon Insertion,当你将这个大括号转移到下一行时,JS引擎"translates"你的代码是这样的:

if (5 > 2) {
  console.log("5 > 2");
} else (5 < 2);
{
  console.log("5 < 2");
}

这显然是正确的,因为JS允许放置独立的块。

解释不同的原因是第一个ECMAScript Rules of Automatic Semicolon Insertion

  1. When, as the program is parsed from left to right, a token (called the offending token) is encountered that is not allowed by any production of the grammar, then a semicolon is automatically inserted before the offending token if one or more of the following conditions is true:

    • The offending token is separated from the previous token by at least one LineTerminator.
    • The offending token is }.

在您的例子中,有问题的标记是 {。在您的代码的第一个版本中,上面引用的要点条件都不成立,因此没有插入分号,并引发了语法错误。

在您的代码的第二个示例中,有一个行终止符,如第一个条件中所述。在这种情况下,会自动插入一个分号,因此解析后的代码实际上变成了这样:

if (5 > 2) {
  console.log("5 > 2");
} else (5 < 2);
{
  console.log("5 < 2");
}

现在代码有效,因为分号后面的大括号被解释为代码块的开头,该代码块不属于 else.

后面的表达式

请注意,即使这段代码现在可以解析,但显然 else 部分中的表达式没有任何效果。