详细解析JS连等a.x=a={n:2}操作
本次文章主要对于下面这道经典面试题做一个解析:
let a = { n: 1 };
let b = a; a.x = a = { n: 2 };
console.log(a.x);//=>undefined
console.log(b);//=>n: 1 x:n: 2
错误思路一:将{ n: 2 }赋值给a,然后再将{ n: 2 }赋值给a.x。
错误思路二:将{ n: 2 }先赋值给a.x,然后在把{ n: 2 }赋值给a。
排雷
有些知识点不明白我们的思路就会陷入雷区,怎么都是错的,所以我们首先要排雷
在这里需要我们先了解一下=的赋值过程,是从右到左一次赋值,将{ n: 2 }赋值给a,然后再将{ n: 2 }赋值给a.x,说道这里有的朋友可能要问了,那为什么第一种思路是错误的呢?
那么我们需要说说js中的运算符优先级问题啦,在js中‘.’的优先级为19,从左到右,而等号的优先级为3,从右到左。数字越大,优先级越高谁就先执行。
关于js运算符更加详细的内容可以参考developer.mozilla.org/zh-CN/docs/…
下面是正解思路:
第一步我们定义了一个对象a,然后定义了一个对象b,将a的值赋给b,这里是引用数据类型赋值和普通数据类型的区别,如果引用数据类型已经被创建,则赋值过程是将a的内存地址赋给b,如果是新创建的一个对象,我们需要另外开辟一个堆内存空间,然后将新的内存地址赋值给b。普通数据类型是另外创建一个值。
第二步 a.x = a = { n: 2 }详细过程:
在赋值的过程中主要有以下三个步骤,
1.先定义变量名(a.x和a此时都对应0x001这个内存地址)
2.然后开辟内存空间将{n:2}这个对象以字符串的形式存储在堆内存中(重新开辟一个内存空间存储{n:2},假如为0x0002)
3.执行赋值操作(将0x0002赋值给a,失去引用的内存地址将会被浏览器在特定时间消除,但是我们此时还有b在指向0x0001地址,所以不会被浏览器回收,然后将0x0002的地址赋值给a.x开辟的引用地址,这在第一步已经确定。其实这个操作是将0x0002的地址赋值给b.x,因为a的引用地址已经改变)
持续更新前端学习心得,喜欢的朋友可以关注我哦
作者:半仙树先生
链接:https://juejin.im/post/5e904f0ce51d4546ea283aab
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。