在这篇文章中,Multiple left-hand assignment with JavaScript,@ Chrescent Fresh说JavsScript左手赋值是正确的。但是在我看来,以下代码打破了正确的关联性:
var a = {n: 1};
a.x = a = {n: 2};
console.log(a.x);// undefined
有人可以解释为什么a.x
未定义?
编辑:上面的代码段是测试"右关联性",在现实世界中请不要写相似的代码。
答案 0 :(得分:7)
这是正确的联想。它只是在语句执行之前将标识符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
的循环引用,但它不是。
有谁可以解释为什么a.x未定义?
是的,行a.x = a = {n: 2}
执行时会发生这种情况:
{n: 2}
分配给变量a
{n: 2}
值被分配给x
引用的对象的a
属性。没有为x
新值的a
属性分配任何内容。这就是a.x
为undefined
的原因。
答案 1 :(得分:6)
tl; dr - JS确定在确定该值之前放置值的位置,并计算出该值的副作用会改变a
的值。
请参阅spec for simple assignment。
第1步是“让lref成为评估LeftHandSideExpression的结果。”
第2步是“让rref成为评估AssignmentExpression的结果。”
所以首先发生的是在x
(其中n为1)中存储的对象上创建属性a
。
然后评估右侧(最终用新对象覆盖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);
答案 2 :(得分:0)
对象通过引用传递。它们永远不会被复制。
var a = {n:1}
所以早些时候有一个具有属性n = 1
的对象的引用在第二个声明中
a.x = a = {n:2}
a.x在前一个对象上添加了属性x,其值为具有属性n = 2的对象
同一语句指定新对象的引用。