Javascript 为什么这个ReferenceError阻止了所有的执行,而这个TypeError没有?
在读取时,有人声称语法错误会阻止执行前面的行<代码>2()代码>和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=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