一个连续赋值的题目

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

无意之中看到的题目,要求输出a.x和b.x的值?

 

首先先说一下答案,a.x为undefined;b.x为{n:2};

我这里用自己的语言整理一下答案, 首先a和b都指向{n:1}这个变量,我们知道在JavaScript中对象是存储在堆内存中,变量就是对象的引用地址。

这一步应该都很好理解,我画了一个图,将{n: 1}称为对象A。

 

 

 

这里是第一步的过程,

之后a.x = a ={n:2};这一点应该是让好多人难以理解的地方。

因为正常执行顺序应该是先赋值a = {n: 2}这一个语句,之后a.x = a。

这样理解是没有错的,不过忽略了最重要的一点,优先级。

 

 

给几个例子,简单举例一下

console.log(1 + 2 * 6); //13
 console.log(2 * 2 ** 6);    //128

 这里可以参考MDN文档,"."运算符在JavaScript中的优先级仅次于"()",运算符优先级​

 

下面这个例子可以很好说明

var a = Object.defineProperty({}, 'f', {
            value: 456,
            writable: false,
        });
        Object.freeze(a);
        var b = a.f = 789;
        console.log(b);    //789
        console.log(a.f);   //456

 这里我定义了变量a,且让他不可修改,如果没有优先级的话,a.f为456,b的值也应该为456。

回到第一个例子,a.x = a ={n:2}; a.x这里会被最先执行,a.x就相当于在对象A的堆内存中添加了一个属性

 

之后执行a = {n: 2},这里因为a的引用类型变更,导致变量a重新指向一个地址(对象B)。

之后执行a.x = a,这一步因为a.x在一开始就已经被执行了,当时a的值指向对象A,x是对象A的一个属性,后面a被修改指向对象B,所以就是将X的值重新赋值于对象B。

但是这时a的地址是指向对象B, 这也是为什么,一开始输出 console.log(a.x);是undefined的原因了,

因为a变量指向的变量B根本就没有x这个属性, 而输出console.log(b.x);指向一个对象{n: 2}的原因了。

 

最后给出一道题,试着解释一下为什么? a.x = a = {};

因为根据运算符规则,a.x最先被执行,a没有被声明为undefined,a.x自然就报错了。

 

转载于:https://www.cnblogs.com/boses/p/9587795.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值