做一个“;不存在变量“;评估到“;未定义的“;非严格代码中的值

Does a "nonexistent variable" evaluate to the "undefined" value in non-strict code?

本文关键字:未定义 代码 变量 一个 不存在 评估      更新时间:2023-09-26

本段来自《JavaScript:最终指南》一书,第6版,第58页:

当任何标识符单独出现在程序中时,JavaScript假设它是一个变量并查找它的值。如果没有带的变量如果该名称存在,则表达式的计算结果为undefined值。然而,在ECMAScript 5的严格模式中,尝试评估不存在的变量会引发ReferenceError。


首先,让我解释一下我是如何理解这段话中使用的一些短语的。

"…标识符在程序中自行出现,…":

我假设作者指的是将标识符解析为表达式的情况(在这种情况下执行标识符解析)。例如:

function func ( arg ) {
    var local = helper( arg );
} 

这里,funcarg(出现两次)、localhelper都是标识符,但只有helperarg(仅出现第二次!)是表达式。因此,只有这两个标识符会导致引用错误。

"…不存在具有该名称的变量…"answers"不存在的变量":

我认为,作者指的是一个标识符,其评估结果为无法解析的引用。


现在,如果我错了,请纠正我,但是。。。

当评估被解析为表达式的标识符(准确地说是aPrimaryExpression)时,执行标识符解析。此过程的结果始终是引用类型的值。换句话说,标识符将评估为引用。

引用有一个基值和一个被引用的名称。引用的名称是标识符的文本,基值是具有该名称绑定的环境记录(包含此类变量的作用域)。但是,如果标识符解析无法解析引用的名称,则引用的基值将为undefined值。

因此,一个"不存在的变量"计算为一个基准值为undefined的引用。

请注意,对不存在的变量的求值不会引发引用错误。稍后,当解释器检索引用的值时(通过GetValue()),会抛出错误。然而,这种情况可能并不总是发生——例如,如果x计算为不可解析的引用,则typeof x不会检索引用的值,因此不会引发引用错误。


我问题开头引用的一段话指出,在非严格代码中,不存在的变量的求值结果为undefined,而在严格代码中对这样一个标识符的求值会引发引用错误。我认为这两个语句都是不正确的——一个不存在的变量计算为基值为undefined的引用,而引用错误是在严格模式下抛出的而不是

当解释器试图检索这样一个引用的值时(这可能会发生,也可能不会发生,这取决于标识符出现在其中的"外部"表达式或语句),会抛出引用错误。这种行为在非严格模式和严格模式之间没有区别。


那么,这个段落正确吗如果没有,我是否正确识别了错误?(此外,如果我的文本中有错误,请更正。)

在非严格代码中,一个"不存在的变量"是否计算为"未定义"值

> foo;
ReferenceError: foo is not defined
> var x = foo;
ReferenceError: foo is not defined

这种行为在严格模式下也是正确的:

> (function () { "use strict"; foo; }());
ReferenceError: foo is not defined
> (function () { "use strict"; var x = foo; }());
ReferenceError: foo is not defined

就变量解析而言,我所知道的严格模式和非严格模式之间的唯一区别是,当分配变量时,如果未声明变量,则会在严格模式下抛出ReferenceError,但在非严格模式下会隐式创建全局变量。

附录C(ECMAScript的严格模式):

对未声明的标识符或无法解析的引用的赋值不会在全局对象中创建属性。当一个简单赋值发生在严格模式代码中时,它的LeftHandSide不能计算为不可解的引用。如果这样做,则引发ReferenceError异常(8.7.2)。

是,即使您使用声明它

var someVar;

它仍然计算为未定义