Javascript 为什么这个ReferenceError阻止了所有的执行,而这个TypeError没有?

Javascript 为什么这个ReferenceError阻止了所有的执行,而这个TypeError没有?,javascript,syntax-error,typeerror,referenceerror,Javascript,Syntax Error,Typeerror,Referenceerror,在读取时,有人声称语法错误会阻止执行前面的行2()和2=3都作为示例给出 但是在Chrome的控制台上测试这个行为时,只有2=3阻止执行前几行 这是2()的输出(我正在使用Shift+Enter): 如您所见,第一行是为2()执行的和foo 1已打印出来。但对于2=3,不打印任何内容 那么,为什么一种类型的错误会阻止打印和执行以前的代码,而另一种类型的错误则不会,并且这种错误依赖于浏览器?这是由于引用错误的性质造成的。Per: 如果您想更好地理解语法和语义,以及这会引发ReferenceErro

在读取时,有人声称语法错误会阻止执行前面的行<代码>2()
2=3都作为示例给出

但是在Chrome的控制台上测试这个行为时,只有
2=3阻止执行前几行

这是
2()的输出(我正在使用Shift+Enter):

如您所见,第一行是为
2()执行的
foo 1
已打印出来。但对于
2=3,不打印任何内容


那么,为什么一种类型的错误会阻止打印和执行以前的代码,而另一种类型的错误则不会,并且这种错误依赖于浏览器?

这是由于
引用错误的性质造成的。Per:

如果您想更好地理解语法和语义,以及这会引发ReferenceError的原因,可以深入研究。根据规范:

-静态语义:早期错误

AssignmentExpression:LeftHandSideExpression=AssignmentExpression

如果
LeftHandSideExpression
既不是
ObjectLiteral
也不是
ArrayLiteral
并且
LeftHandSideExpression
IsValidSimpleAssignmentTarget
为false,则这是早期引用错误

其中,
IsValidSimpleAssignmentTarget
是:

-静态语义:IsValidSimpleAssignmentTarget

AssignmentExpression :
  YieldExpression
  ArrowFunction
  LeftHandSideExpression = AssignmentExpression
  LeftHandSideExpression AssignmentOperator AssignmentExpression
一,。返回false

如您所见,如果赋值符合
AssignmentExpression:LeftHandSideExpression=AssignmentExpression
的定义,则会引发“早期错误”,但
LeftHandSideExpression
无效。由于
2
不是
ObjectLiteral
ArrayLiteral
,并且
IsValidSimpleAssignmentTarget
返回false,因此赋值失败,并引发
ReferenceError

现在,来定义术语“早期错误”。根据规范:

[…]早期错误是指在评估包含该错误的任何构造之前可以检测并报告的错误

这意味着当出现早期错误时,不会执行任何代码。因为在您的分配中,会引发早期的
ReferenceError
,不会执行任何代码,因此控制台永远不会登录到

在第二个示例中,执行了一个测试。评估的步骤5抛出一个
TypeError
,因为的结果为false(因为
func
是一个
Number
),并且抛出
TypeError
。请注意,
TypeError
不是早期错误。因此,代码确实会执行,并且控制台会记录到。当行<代码>2()时时,将对其求值并抛出
TypeError

这不依赖于浏览器,因为所有浏览器和JavaScript引擎都必须遵循规范。应该注意的是,这是从ECMAScript®2015(又名ES6)规范中提取的,该规范尚未在所有引擎上完全实施。我建议看一看(ES5)规范,在该规范中,所有现代引擎都完全实现了,尽管上述定义在两个版本之间没有改变


应该注意的是,这些不是语法错误<代码>2()
是一个
类型错误
,因为
编号
类型不可调用
2=3
是一个
ReferenceError
,因为
2
是一个要分配给的无效左侧。但是,将函数指定给一个数字名称是一个语法错误。它违反了to do
函数2(){}
的语法,因为该声明要求将an作为名称


一个数字是一个常数,你不能给任何东西分配一个常数,因为它是常数
2=3
在现实世界中没有意义,因此在规范中被阻止。类似地,您不能执行
var 2=function(){}
这是由于
引用错误的性质造成的。Per:

如果您想更好地理解语法和语义,以及这会引发ReferenceError的原因,可以深入研究。根据规范:

-静态语义:早期错误

AssignmentExpression:LeftHandSideExpression=AssignmentExpression

如果
LeftHandSideExpression
既不是
ObjectLiteral
也不是
ArrayLiteral
并且
LeftHandSideExpression
IsValidSimpleAssignmentTarget
为false,则这是早期引用错误

其中,
IsValidSimpleAssignmentTarget
是:

-静态语义:IsValidSimpleAssignmentTarget

AssignmentExpression :
  YieldExpression
  ArrowFunction
  LeftHandSideExpression = AssignmentExpression
  LeftHandSideExpression AssignmentOperator AssignmentExpression
一,。返回false

如您所见,如果赋值符合
AssignmentExpression:LeftHandSideExpression=AssignmentExpression
的定义,则会引发“早期错误”,但
LeftHandSideExpression
无效。由于
2
不是
ObjectLiteral
ArrayLiteral
,并且
IsValidSimpleAssignmentTarget
返回false,因此赋值失败,并引发
ReferenceError

现在,来定义术语“早期错误”。根据规范:

[…]早期错误是指在评估包含该错误的任何构造之前可以检测并报告的错误

这意味着当出现早期错误时,不会执行任何代码。因为在您的分配中,会引发早期的
ReferenceError
,不会执行任何代码,因此控制台永远不会登录到

在第二个示例中,执行了一个测试。评估的步骤5抛出一个
TypeError
,因为的结果为false(asAssignmentExpression : YieldExpression ArrowFunction LeftHandSideExpression = AssignmentExpression LeftHandSideExpression AssignmentOperator AssignmentExpression