一个小问题:js 连等问题

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

很多人没仔细考虑的话,会认为 a.x 应该是 {n:2},因为我们都知道,"="  赋值运算符是自右向左的:

a.x = a = {n:2};

这句话就可以理解为 : 将  a = {n:2} (后面称为对象B)的返回值赋值给 a.x。这么想的话,就忽略了这个表达式里包含的另一个运算符 “.”,即字段访问运算符(或者叫成员运算符?),明显字段访问运算符优先级是要比赋值运算符要高的,因此,这段代码在进行赋值运算前,会先解析 a.x,此时 a 还指向 {n:1}(后面称为对象A),对象A中找不到x属性,则给A增加x 属性,值为 undefined,A变成 {n:1, x:undefined}。然后进行赋值运算将 a和对象A的x属性指向对象B,此时 b = A  = {n:1, x:{n:2}}, a = B = {n:2}; 很明显 对象B是没有x属性的,a.x自然打印 undefined。下面的图更形象一些:

第一行: let a = {n:1},在堆内存中创建 对象A,栈中创建变量 a 指向 对象A

第二行:let b = a,栈中创建变量 b 指向 a指向的堆中的 对象A

第三行:a.x = a = {n:2},这里可以分成两步:

      第一步:“计算” a.x,给堆中 对象A 增加 x属性,不赋值即为 undefined。

       

      第二步计算 a.x = a = {n:2}:

       

     首先在堆中创建 对象B,将 a 指向 对象B。因为 a.x 的计算是在此赋值之前,所以此时 a.x 指向的是 对象Ax属性

     然后将 对象Ax属性 指向对象B

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值