在这篇文章中,使用JavaScript进行多项左手赋值 @Crescent Fresh说JavsScript左手赋值是正确的.但是在我看来,以下代码打破了正确的关联性:
var a = {n: 1}; a.x = a = {n: 2}; console.log(a.x);// undefined
任何人都可以解释为什么a.x
未定义?
编辑:上面的代码片段是测试"正确的关联性",在现实世界中请不要编写类似的代码.
这是正确的联想.它只是a
在语句执行之前将标识符绑定到引用.
我们可以通过以下方式见证这一点:
var a, b; a = b = { n: 1 }; a.x = a = {n: 2}; // a.x refers to the x property of the value a references // before this statement executes console.log(a); // {n: 2} console.log(b); // {n: 1, x: {n: 2}}
如果=
是左关联的,则在第三行执行后b.x
返回循环引用b
,但事实并非如此.
任何人都可以解释为什么ax未定义?
是的,这是行a.x = a = {n: 2}
执行时发生的事情:
该值{n: 2}
将分配给变量a
该值{n: 2}
将分配给语句开始执行之前引用x
的对象的属性.a
没有赋予新值的x
属性a
.这就是为什么a.x
是undefined
.
tl; dr - JS确定在确定该值之前放置值的位置,以及计算该值的副作用会改变其值a
.
请参阅规范以进行简单分配.
第1步是"让lref成为评估LeftHandSideExpression的结果".
第2步是"让rref成为评估AssignmentExpression的结果".
所以首先发生的是x
在存储的对象上创建一个属性a
(其中n是1).
然后评估右侧(最终a
用新对象覆盖,其中n为2).
然后将该表达式的结果(该对象,其中n为2)分配给x
原始对象(其中n为1).
你可以看到这个有效:
"use strict";
var a = {n: 1};
var b = a;
a.x = a = {n: 2};
console.log(a);
console.log(b);