JS 连续等号赋值问题

最近在GitHub上发现一个有意思的问题,如下:

var foo = {n: 1};
var bar = foo;
foo.x = foo = {n: 2};
console.log(foo.x);  // undefined
console.log(bar); //  Object {n: 1, x: {n:2}}

运行结果显示 foo.x 的值为 undefined,分析过程如下:

ECMAScript 规范指出:

  1. Let lref be the result of evaluating LeftHandSideExpression.
  2. ReturnIfAbrupt(lref).
  3. Let rref be the result of evaluating AssignmentExpression.
  4. Let rval be GetValue(rref).
    […]

大致意思是,对于 类似 A=B 的表达式,首先计算A表达式,得到 lref,然后计算计算表达式 B,
得到 B 的值 rval,将 rval 赋给 lref 指向的变量,返回 rval。

JS的赋值表达式是右结合的,所以 foo.x = foo = {n:2} 等价于 foo.x = ( foo = { n : 2} )

根据计算顺序,

  1. 计算出括号内的值,然后赋给 foo.x。
  2. 得到 foo.x = { n : 2 },同时 bar.x = { n : 2 } ,左边第一个等号的计算结束。
  3. 然后计算括号内的表达式,即 foo = { n : 2 }。
  4. foo 被赋予新的对象,不再是原来对象的引用,指向了 { n : 2 },所以foo.x
    得到的是 undefined, 但是 bar 依旧指向原来的对象,所以bar值没有改变。

此段代码等同于如下的代码:

var foo = {n: 1};
var bar = foo;
var foo1 = {n: 2};
foo.x = foo1;
foo = foo1;
console.log(foo.x,bar);
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值