连等的思考

1,233 阅读2分钟

年前写了一篇博客,立了一个flag说是以后一个星期写一篇博客,但被年前的997和过年给耽误了,算了一下一共欠了四篇博客,后续会补上

从18年到这篇博客之前都是在简书上写,当然写的都是一些浅显一点的东西,也获得了几十个粉丝和不少赞(惭愧),写的都是一些工具的使用,经过了一年的磨练以后,后面也会写一点稍微深入一点的东西,或者是更原理一些的东西,望共勉

昨天水群的时候看到有人发了一道很有意思的面试题,看起来简单,但是答错的人倒是占了十之八九,还有一些人可能是之前看过类似的题,但是解释的也是差强人意,所以就自己研究了一番

题目是这样的

  var obj = {n:1}
  var newObj = obj
  obj.m = obj = {n:2}
  console.log(obj)
  console.log(newObj)

题目就这么长,答案是 obj = {n: 2}, newObj = {n: 1, m: {n:2}}

小伙伴们答对了吗?

其实这个题的关键内容是obj.m = obj = {n:2}这行代码,只要搞明白这句话的执行顺序,这题就很简单了,执行顺序如下

  • 查看当前obj当前是否有m属性,没有就声明一个m属性
  • 然后obj.m=xx是一个表达式等待,需要等待后面的执行结果
  • 执行obj = {n:2},重新为obj分配一个堆内存空间,obj指向这个新的内存空间,obj={n:2},执行的结果就是新内容空间的指针地址 如图所示: 先创建obj执行一个堆地址,并且把newObj也指向这个地址,添加m属性

重新为obj分配空间

赋值到左侧的时候m的属性值指向了obj的新内存地址

这个时候我们在测试一下

  var obj = {n:1}
  var newObj = obj
  obj.m = obj = {n:2}
  //改变n的值
  obj.n = 100
  console.log(obj)     //{n: 100}
  console.log(newObj)  //{n: 1,m: {n: 100}}