这是由于ReferenceError 的性质造成的。每an answer of mine:
如果您想更好地理解语法和语义,以及为什么会引发 ReferenceError,您可以深入研究ECMAScript® 2015 Language Specification。根据规范:
Section 12.14.1 - Assignment Operators - 静态语义:早期错误
AssignmentExpression : LeftHandSideExpression = AssignmentExpression
如果 LeftHandSideExpression 既不是 ObjectLiteral 也不是 ArrayLiteral,这是一个早期参考错误 和 IsValidSimpleAssignmentTarget 的 LeftHandSideExpression 为假。
IsValidSimpleAssignmentTarget 在哪里:
Section 12.14.3 - Assignment Operators - 静态语义:IsValidSimpleAssignmentTarget
AssignmentExpression :
YieldExpression
ArrowFunction
LeftHandSideExpression = AssignmentExpression
LeftHandSideExpression AssignmentOperator AssignmentExpression
1。返回 false。
如您所见,如果赋值符合 AssignmentExpression : LeftHandSideExpression = AssignmentExpression 的定义但 LeftHandSideExpression 无效,则会引发“早期错误”。由于2 不是ObjectLiteral,ArrayLiteral 和IsValidSimpleAssignmentTarget 返回 false,分配失败并抛出 ReferenceError。
现在,定义术语“早期错误”。根据规范:
Section 16 - Errors
[...]早期错误是可以在评估包含错误的Program 中的任何构造之前检测和报告的错误。
这意味着当出现早期错误时,不会执行任何代码。因为在您的作业中,提早出现了ReferenceError,没有执行任何代码,因此,控制台永远不会被登录。
在第二个示例中,执行function call。评估的第 5 步抛出 TypeError,因为 IsCallable(func) 的结果为假(因为 func 是 Number),并且 TypeError 被抛出。请注意,TypeError不是早期错误。因此,确实发生了代码的执行,并且控制台被记录到。当遇到2(); 行时,对其求值并抛出TypeError。
这不依赖于浏览器,因为所有浏览器和 JavaScript 引擎都必须遵循规范。应该注意的是,这取自 ECMAScript® 2015 (AKA ES6) 规范,该规范尚未在所有引擎上完全实现。我建议查看ECMAScript® 2011 (ES5) 规范,其中所有现代引擎都完全实现,尽管上述定义在两个版本之间没有改变。
请注意,这些不是语法错误。 2(); 是 TypeError,因为 Number 类型不可调用。 2 = 3 是 ReferenceError,因为 2 是要分配到的无效左侧。但是,将函数分配给数字名称是语法错误。执行function 2() {} 违反了function declaration 的语法,因为声明需要identifier 作为名称。
数字是一个常数,你不能给任何东西赋值,因为它是常数。 2 = 3 在现实世界中毫无意义,因此在规范中被禁止。同样,你不能做var 2 = function() {}。