通过a.x=a={n:2}连续赋值,了解内存指针和堆栈

在了解js的内存数据类型发现一道题,打算结合大佬的文章写一下自己理解,通过画图把这个题目解析更加直观化。

题目

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

题目考察是对变量和值在堆栈中的存储以及变量指针的指向,还有就是运算符优先级

先把答案给大家:undified,{n:1,{n:2}}

一.先解释一下这里的运算符优先级

`我们知道运算符的优先级决定了表达式中运算执行的先后顺序,优先级高的运算符最先被执行。`
赋值运算顺序是从右往左的,不过由于“.”是优先级最高的运算符,所以 
 a.x = a = {n:2} 这行代码先“执行”了a.x;

二.顺序执行代码

  1. var a={n:1};  a指向了堆内存中的对象{n:1}(我们姑且称呼这个对象为A),  var b=a; a赋予给b的时候传的是栈中的地址(相当于新建了一个不同名“指针”) ,而不是堆内存中的对象。

  2. a.x = a = {n: 2} ;前面说了“.”的优先级大于赋值运算符的优先级,所以我们先进行属性操作,会先执行a.x,此时虽然并没有给x赋值,但是还是会给a指向的对象添加一个属性x,值为undefined

  3. a.x = a = {n: 2},执行完a.x后接下来从右向左开始赋值,将a的指向从对象A指向了对象B{n:2}

  4. 接下来继续执行 a.x=a,很多人会认为这里是“对象B也新增了一个属性x,并指向对象B自己”,很多人这样认为是错误的,根据优先性( .  运算符最先计算),咱们刚才已经计算过a. x,那时变量a的指向还是对象A,变量a指针并没有发生变化,所以此时a.x确切地说应该是对象A.x,代码再次执行时,指针发生了变化,a的指针指向B,此时a.x=a再赋值时不再次执行依次a.x然后再赋值,这样系统不允许,而是直接赋值,相当于之前的A.x赋值,所以 a.x=a 应理解为对象A的属性x指向了对象B:

  5. 所以根据图表很容易得出结果当console.log(a.x)的时候,a是指向对象B的,但对象B没有属性x。没关系,当查找一个对象的属性时,JavaScript 会向上遍历原型链,直到找到给定名称的属性为止。但当查找到达原型链的顶部 - 也就是 Object.prototype - 仍然没有找到指定的属性B.prototype.x,自然也就输出undefined。而在console.log(b.x)的时候,由于b.x表示对象A的x属性,该属性是指向对象B,自然也输出{ n: 2 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值