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:
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
部分中的表达式没有任何效果。
这段代码显然有问题:
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:
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
部分中的表达式没有任何效果。