使用JavaScript进行多项左手分配,真的是正确的关联吗?

时间:2015-12-19 14:47:53

标签: javascript

在这篇文章中,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未定义?

编辑:上面的代码段是测试"右关联性",在现实世界中请不要写相似的代码。

3 个答案:

答案 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}执行时会发生这种情况:

  1. 将值{n: 2}分配给变量a
  2. 在语句开始执行之前,{n: 2}值被分配给x引用的对象的a属性。
  3. 没有为x新值的a属性分配任何内容。这就是a.xundefined的原因。

答案 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)

java脚本中的

对象通过引用传递。它们永远不会被复制。

var a = {n:1}

所以早些时候有一个具有属性n = 1

的对象的引用

在第二个声明中     a.x = a = {n:2} a.x在前一个对象上添加了属性x,其值为具有属性n = 2的对象 同一语句指定新对象的引用。