【问题标题】:Why does this ReferenceError prevent all execution when this TypeError does not?为什么这个 ReferenceError 阻止所有执行,而这个 TypeError 没有?
【发布时间】:2017-02-24 16:39:00
【问题描述】:

在读取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;,没有打印任何内容。

那么为什么一种类型的错误会阻止打印和执行先前的代码,而另一种则不会,这是否取决于浏览器?

【问题讨论】:

    标签: javascript syntax-error typeerror referenceerror


    【解决方案1】:

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

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

    Section 12.14.1 - Assignment Operators - 静态语义:早期错误

    AssignmentExpression : LeftHandSideExpression = AssignmentExpression

    如果 LeftHandSideExpression 既不是 ObjectLiteral 也不是 ArrayLiteral,这是一个早期参考错误 IsValidSimpleAssignmentTargetLeftHandSideExpression 为假。

    IsValidSimpleAssignmentTarget 在哪里:

    Section 12.14.3 - Assignment Operators - 静态语义:IsValidSimpleAssignmentTarget

    AssignmentExpression :
      YieldExpression
      ArrowFunction
      LeftHandSideExpression = AssignmentExpression
      LeftHandSideExpression AssignmentOperator AssignmentExpression
    

    1。返回 false。

    如您所见,如果赋值符合 AssignmentExpression : LeftHandSideExpression = AssignmentExpression 的定义但 LeftHandSideExpression 无效,则会引发“早期错误”。由于2 不是ObjectLiteralArrayLiteralIsValidSimpleAssignmentTarget 返回 false,分配失败并抛出 ReferenceError

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

    Section 16 - Errors

    [...]早期错误是可以在评估包含错误的Program 中的任何构造之前检测和报告的错误。

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

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

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


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

    数字是一个常数,你不能给任何东西赋值,因为它是常数。 2 = 3 在现实世界中毫无意义,因此在规范中被禁止。同样,你不能做var 2 = function() {}

    【讨论】:

      猜你喜欢
      • 2011-01-06
      • 2011-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多