酒浓码浓 - js赋值顺序/var a = {n: 1}   var b = a   a.x = a = {n: 2}   console.log(a.x)  console.log(b.x)

赋值顺序

以下为网上一个非常经典的面试题:

var a = {n: 1}  
var b = a;  
a.x = a = {n: 2}  
console.log(a.x);  
console.log(b.x) 

OK我们来解答一下

声明!!!曾经的认知:

第一个知识点:

b = a 是浅拷贝,所以在堆栈中引用的是一个对象地址。

第二个知识点:

var a=1,b=2,c=3;

a = b = c;

输出的a,b,c结果都为3。  因为赋值运算从右向左执行

而我们这道题 a.x = a = {n: 2} 

. 的运算优先级大于赋值运算的优先级。 

所以先计算

再计算

所以截止到现在

a的输出值:{ n:2 };

b的输出值:{ n:1 , x={n:2} }

 

OK, 看明白了我们随便改动来练习一下:

所以截止到现在

a,b的输出都是一个值:{n={n:2}, f={n:2}}

我们来验证一下:

 

新的认识:

在阅读了javascript引擎的原理解析后有了新的认识。

此题的衍化源自于Jquery的提交者之一 蔡美纯(蔡mc)

虽然按上述文章的思路算的题结果是没问题的,但是概念的理解是有误区的,所以在这里重新阐述一下。

JavaScript的计算是从左至右的

例:

var a = x + y * z

a在此处是个字面量,后面的为表达式,计算后赋值给a

 

var a = {n:1}

a.x = a = {n: 2}

a.x在此处是个表达式,所以参与从左到右的运算(此处纠正:历史的阐述是 . 的运算符优先于 = 赋值运算符

此处可以用Object.freeze(a)冻结a去验证,可以清晰验证结论。

 

解析:

a.x = " 表达式 a={n:2} ",表达式将计算结果赋值给a.x

a = {n:2}的结果为{n:2} 

注:a 在此过程中被真实的赋值了一次 {n: 2},但是 a.x 中的 a 此时不会更新,它等待的是一个运行结果,这个结果只有引擎知道,对于它的操作只能为取值或置值(GetValue/PutValue),以及作为一个引用向别的地方传递等。实际上a的值已经为{n: 2},但体现不出来,相当于被"空置"了。

b=a是先行的,a.x中的a等待的运行结果为: {n:1, x:{n:2}} 。

如果将 var b=a放在a.x之后,结果就会等于空置的a 

所以

a的输出值:{ n:2 };

b的输出值:{ n:1 , x:{n:2} }

 

扫描二维码关注公众号

每日好文伴你地铁时光。

 

  • 11
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值