3 回答
TA贡献1853条经验 获得超9个赞
foo.x = foo = {n: 2};
判定foo.x是指一种属性x的的{n: 1}目的,分配{n: 2}给foo,并分配的新值foo- {n: 2}-为属性x的的{n: 1}对象。
重要的是,foo这foo.x指的是之前确定foo的变化。
参见ES5规范的11.13.1节:
令lref为评估LeftHandSideExpression的结果。
令rref为评估AssignmentExpression的结果。
赋值运算符从右到左关联,因此您得到:
foo.x = (foo = {n: 2})
首先评估左侧,然后评估右侧。
TA贡献1936条经验 获得超6个赞
foo.x = foo = {n:2};
此处foo指的是赋值之前即执行语句之前的{n:1}对象。
该语句可以重写为foo.x =(foo = {n:2});
在对象方面,以上语句可以重写为 {n:1} .x =({n:1} = {n:2});
由于分配仅从右到左发生。因此,这里我们只需要在执行开始之前检查foo是否指向哪个对象。
在解决RHS时: foo = {n:2} ; 现在foo指的是{n:2};
回到我们剩下的问题:
foo.x = foo;
现在,LHS上的foo.x仍然是{n:1} .x,而RHS上的foo是{n:2}。
因此,在执行该语句后,{n:1}将变为{n:1,x:{n:2}},并且bar仍引用该语句。凡为FOO现在将参照{N:2} 。
因此,在执行foo.x时会给出undefined,因为foo中只有1个值为{n:2}的值。
但是,如果您尝试执行bar.x,它将得到{n:2}。或者,如果您只执行bar,结果将是
对象{n:1,x:对象}
TA贡献1846条经验 获得超7个赞
我以为我会添加另一种我认为有用的思考方式。
最后的变量分配等同于write bar.x = foo = {n:2};,因为这些变量只是对内存中同一事物的引用。
换句话说,foo和bar首先都引用相同的对象{n:1}。使用时foo.x =,您正在访问{n:1}该x属性并将其添加到其中。这可以通过任一方法完成,bar或者foo因为它们都指向内存中的同一对象!这没什么区别。
然后,当您完成该行时,foo.x = foo = {n:2}您将通过对象文字语法在内存中创建另一个全新的对象,并设置foo为指向该对象{n:2},而不是现在的对象{n:1, x: {n: 2}。但是,这不会影响foo将x属性添加到该属性时所指向的内容。
这非常令人困惑,但是我认为您可以考虑这样一个事实,即变量只是指向内存中的位置/对象的指针,并且对象文字语法不会更改先前存在的对象(即使它们看起来很相似)。它正在创造一个全新的。
添加回答
举报