在阅读PluralSight Tutorial时,声称语法错误会阻止执行前一行。 2();
和2 = 3;
都是作为示例提供的。
但是在Chrome的控制台中测试此行为后,只有2 = 3;
阻止了以前的行执行。
以下是2();
的输出(我正在使用 Shift + Enter ):
console.log("foo 1");
2();
console.log("foo 2");
VM224:1 foo 1
VM224:2 Uncaught TypeError: 2 is not a function
at <anonymous>:2:2
这是2 = 3;
console.log("foo 1");
2 = 3;
console.log("foo 2");
VM202:2 Uncaught ReferenceError: Invalid left-hand side in assignment
如您所见,第一行是2();
执行的,foo 1
已打印出来。但是对于2 = 3;
,没有任何内容被打印出来。
那么为什么一种类型的错误阻止了先前代码的打印和执行,而另一种则没有,并且这是依赖于浏览器的吗?
答案 0 :(得分:4)
这是由于ReferenceError
的性质。每an answer of mine:
如果您想更好地理解语法和语义,以及为什么会引发ReferenceError,您可以深入研究ECMAScript® 2015 Language Specification。根据规范:
Section 12.14.1 - Assignment Operators - 静态语义:早期错误
如果
AssignmentExpression : LeftHandSideExpression = AssignmentExpression
LeftHandSideExpression
既不是ObjectLiteral
也不是 {这是一个早期参考错误
和ArrayLiteral
的{1}}IsValidSimpleAssignmentTarget
为false。
LeftHandSideExpression
的位置:
Section 12.14.3 - Assignment Operators - 静态语义:IsValidSimpleAssignmentTarget
IsValidSimpleAssignmentTarget
1。返回false。
如您所见,如果作业符合 AssignmentExpression :
YieldExpression
ArrowFunction
LeftHandSideExpression = AssignmentExpression
LeftHandSideExpression AssignmentOperator AssignmentExpression
的定义但 AssignmentExpression : LeftHandSideExpression = AssignmentExpression
无效,则会引发“早期错误” 。由于LeftHandSideExpression
不是 2
, ObjectLiteral
,而ArrayLiteral
返回false,因此分配失败并且{ {1}}被抛出。
现在,定义术语“早期错误”。根据规范:
<强> Section 16 - Errors 强>
[...] 早期错误是在评估包含错误的
Program
中的任何构造之前可以检测和报告的错误。
这意味着当引发早期错误时,不会执行任何代码。因为在你的作业中,引发了早期的IsValidSimpleAssignmentTarget
,所以没有执行任何代码,因此,控制台永远不会被记录。
在第二个示例中,执行function call。评估的第5步会引发ReferenceError
,因为IsCallable(func)
的结果为假(ReferenceError
为TypeError
),并且func
被抛出。请注意,Number
不是早期错误。因此,代码的执行确实发生,并且控制台被记录到。遇到行TypeError
时,会对其进行评估并抛出TypeError
。
这不依赖浏览器,因为所有浏览器和JavaScript引擎都必须遵循规范。应该注意的是,这取自ECMAScript® 2015 (AKA ES6)规范,该规范尚未在所有引擎上完全实现。我建议看看ECMAScript® 2011(ES5)规范,其中所有现代引擎都完全实现,但上述两个版本之间的定义没有变化。
应该注意,这些不是语法错误。 2();
是TypeError
,因为2();
类型不可调用。 TypeError
是Number
,因为2 = 3
是要分配的无效左侧。但是,将函数分配给数字名称是语法错误。它违反function declaration做ReferenceError
的语法,因为声明需要identifier作为名称。
数字是常量,您不能为任何事物分配常量,因为它是常量。 2
在现实世界中毫无意义,因此在规范中被禁止。同样,您无法执行function 2() {}
。