js 对象赋值_js连续赋值及js引用类型指针(赋值从右往左)

JavaScript中的连续赋值:

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

再看下个例子

var a = {x:{xx:1},y:2,z:3};
var b = a.x;  //{xx:1}
var c = a;
a.w = a.x.xx = a.y = a = {x:10,y:20};
console.log(a); // a:{x: 10, y: 20}
console.log(b); // b:{xx : {x: 10, y: 20}}
console.log(c); // c:{x:{xx:{x:10,y:20}},y:{x:10,y:20},z:3,w:{x:10,y:20}}
 
console.log(c.x.xx.x);//10
console.log(c.y.x);//10
console.log(c.w.x);//10

我们先回头看第一个例子:

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

正解:

下面来分析下这段简单代码的工作步骤,从而进一步理解js引用类型“赋值”的工作方式。

首先是

var a = {n:1}; 
var b = a;  

在这里a指向了一个对象{n:1}(我们姑且称它为对象A),b指向了a所指向的对象,也就是说,在这时候a和b都是指向对象A的:

57400b778b3041271d5f8d388c891189.png

接着继续看下一行非常重要的代码:

这句话也是关键所在

  • 画图

根据js引擎语法解析,会先去从左到右寻找有没有未声明的变量,如果有就把该变量提升至作用域顶部并声明该变量。那么恭喜js引擎他找到a.x这个属性没有声明,那么他会在{n: 1}这个内存区声明一个x属性等待赋值!

如下图:

563b098e34491ae3d56a3c59a199e7c4.png

从图上可以看到,由于b跟a一样是指向对象A的,要表示A的x属性除了用a.x,自然也可以使用b.x来表示了

语法解析完成后,开始进行运算(ps:赋值运算),首先依循“从右往左”的赋值运算顺序先执行 a={n:2} ,这时候,将a变量的指针指向了一个新的内存区{n: 2},(我们称为对象B),那么a变量脱离了对内存区{n: 1}的引用关系。

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

4729556544fcd66c6fa43868462f4886.png

但是此时{n:1}这个内存区并没有被GC回收因为b变量的指针依然指向它。并且因为之前就声明了x属性所以该内存区增加了X属性。那么X属性指向哪儿呢?

a.x = a = {n: 2}

接着继续执行 a.x=a,很多人会认为这里是“对象B也新增了一个属性x,并指向对象B自己”

但实际上并非如此,由于一开始js已经在对象A中生成了x:undefined属性,则原来的a.x实际上是A.x,

a.x = a = {n:2}; 但是由于赋值运算从右向左运算,所以a.x 在这个式子中 最终被指向了 {n:2} ,也就是对象B即A.x指向 对象B

7765f63ad1be370b1c7eee212910591d.png

那么这时候结果就显而易见了。当console.log(a.x)的时候,a是指向对象B的,但对象B没有属性x。没关系,当查找一个对象的属性时,JavaScript 会向上遍历原型链,直到找到给定名称的属性为止。但当查找到达原型链的顶部 - 也就是 Object.prototype - 仍然没有找到指定的属性B.prototype.x,自然也就输出undefined;

而在console.log(b.x)的时候,由于b.x表示对象A的x属性,该属性是指向对象B,自然也输出了[object Object]了,注意这里的[object Object]可不是2个对象的意思,对象的字符串形式,是隐式调用了Object对象的toString()方法,形式是:”[object Object]”。所以[object Object]表示的就只是一个对象罢了:)

参考:https://blog.csdn.net/qq_41893551/article/details/80996634

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值