javascript - 为什么此 ReferenceError 会阻止所有执行,而此 TypeError 不会?

标签 javascript syntax-error typeerror referenceerror

在阅读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;,则不会打印任何内容。

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

最佳答案

这是由于 ReferenceError 的性质造成的。每an answer of mine :

如果您想更好地理解语法和语义,以及为什么会抛出 ReferenceError,您可以深入研究 ECMAScript® 2015 Language Specification 。根据规范:

Section 12.14.1 - Assignment Operators - Static Semantics: Early Errors

AssignmentExpression : LeftHandSideExpression = AssignmentExpression

It is an early Reference Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget of LeftHandSideExpression is false.

其中 IsValidSimpleAssignmentTarget 是:

Section 12.14.3 - Assignment Operators - Static Semantics: IsValidSimpleAssignmentTarget

AssignmentExpression :
  YieldExpression
  ArrowFunction
  LeftHandSideExpression = AssignmentExpression
  LeftHandSideExpression AssignmentOperator AssignmentExpression

1. Return false.

如您所见,如果赋值符合 AssignmentExpression : LeftHandSideExpression = AssignmentExpression 的定义,但 LeftHandSideExpression 无效。由于 2 不是 ObjectLiteralArrayLiteralIsValidSimpleAssignmentTarget 返回 false,赋值失败并抛出 ReferenceError

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

Section 16 - Errors

[...] An early error is an error that can be detected and reported prior to the evaluation of any construct in the Program containing the error.

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

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

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


需要注意的是,这些不是语法错误。 2();TypeError,因为 Number 类型不可调用。 2 = 3ReferenceError,因为 2 是要分配的无效左侧。然而,将函数分配给数字名称是语法错误。它违反了 function declaration 的语法执行 function 2() {},因为声明需要 identifier作为名称。

数字是一个常量,你不能将常量分配给任何东西,因为它是常量。 2 = 3 在现实世界中没有任何意义,因此在规范中被阻止。同样,您不能执行 var 2 = function() {}

关于javascript - 为什么此 ReferenceError 会阻止所有执行,而此 TypeError 不会?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42443861/

相关文章:

jQuery 类型错误 : 'undefined' is not a function on AJAX submit

javascript - 用于重新加载包含 php 的 div 内容的按钮

javascript - 服务器验证失败后,模式中的 js 停止工作 ASP.NET MVC Core

PHPMyadmin 不显示 mysql 错误信息

javascript - TypeError: this.reduce 不是一个函数

javascript - 为什么我在这个简单的 Meteor 应用程序中得到“"Uncaught TypeError: Cannot read property ' helpers' of undefined”?

javascript - 当用户喜欢帖子时如何动态更新 Flask 模板?

javascript - backbone.js 中模型之间的关系

c - "assignment makes integer from pointer without a cast -wint-conversion"

oracle - 如何将记录类型值传递给函数参数