我正在阅读《学习 Node》一书,我陷入了一个非常简单的问题,一个我没有过多考虑的问题:javascript 中的赋值。
作者指出,我们应该意识到,通过使用 Node 的 REPL,以下内容将返回 undefined:
var a = 2
(undefined)
下面的代码将在 REPL 中返回“2”:
a = 2
2
这是为什么呢?上面的代码不是归属?怎么会?如果 var 'a' 直到代码中的这一点才存在,为什么它不存在并且归属?
根据 ECMA-262 § 12.2,VariableStatement(即
var identifier=value
)显式不返回任何内容。 此外,VariableStatement 是一个语句;语句不返回值,将语句放在表达式所在的位置是无效的。
例如,以下内容都没有意义,因为它们在您需要产生值的表达式的地方放置了一条语句:
var a = var b;
function fn() { return var x; }
根据 § 11.13.1,对变量 (identifier=value
) 的
赋值会返回分配的值。
当您写入
var a = 1;
时,它会声明 a
并将其值初始化为 1
。 因为这是一个 VariableStatement,所以它不返回任何内容,并且 REPL 打印 undefined
。
a=1
是将 1
赋值给 a
的表达式。 由于没有 a
,JavaScript 在普通代码中隐式创建了 global a
(但在严格模式下会抛出 ReferenceError
,因为不允许在严格模式下隐式创建新的全局变量)。
无论
a
之前是否存在,表达式仍然返回指定的值 1
,因此 REPL 会打印该值。
只是在这里猜测 - 这可能可以通过参考 ECMAScript 第五版规范来验证(但是这件事很痛苦) - 它可能与“var”语句的规范与将属性分配给“global”有关对象。
当您声明一个变量并为其赋值时(
var a=2
),返回的值可能是“未定义”,因为这就是规范所说的“var”语句应该返回的值。
当您在不使用“var”语句的情况下将变量分配给符号时,您实际上是在将值分配给该名称的全局对象的属性。 也就是说,
a=2
与 window.a=2
相同,我们知道为属性赋值会返回指定的值。
var a = 2
是一个声明。因此它没有价值。
您正在评估语句列表。当评估语句列表时,返回最后一个产生值的语句的值。 http://ecma-international.org/ecma-262/5.1/#sec-12.1 - 请注意本节末尾的示例。如果列表中没有语句返回值,则不会返回任何内容(这在 JavaScript 中是
undefined
)。
变量声明,不返回值。 http://ecma-international.org/ecma-262/5.1/#sec-12.2
赋值运算符确实返回一个值(以及执行赋值)。 http://ecma-international.org/ecma-262/5.1/#sec-11.13.1