关于 a.x = a = { n: 2 } 面试题解析

432 阅读2分钟

一、面试题介绍

面试题代码如下:

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

为什么console.log(a.x) 的结果是 undefined,想要理解该面试题的运行结果,需要通过以下2点进行拆解分析:

1、通过拆解代码画出内存图,这样更好去理解,看代码的执行逻辑更加直观;

2、了解运算符的优先级【重要】;

二、面试题解析

首先我们针对以上代码,从上往下拆解,画出代码的内存图解:

  var a = { n: 1 }

创建一个a对象,此时a指针指向{ n: 1 }

image-20220227175859630

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

创建一个b对象,并把a赋值给b,此时a和b的指针指向相同,都指向{ n: 1 }

image-20220227175939339

  var a = { n: 1 }
  var b = a
  a.x = a = { n: 2 }

a.x = a = { n: 2 } 这里的代码执行顺序不是从右向左按照顺序进行赋值执行的,这里要注意运算符的优先级,a.x 属于成员访问运算符类型,优先级要比 赋值运算符类型要高很多(如下图链接中的图片:成员访问运算符类型的优先级是18,而赋值运算符类型是2),所以 a.x 优先于 a = { n: 2 } ` 执行。

developer.mozilla.org/zh-CN/docs/…

image-20220227191244155

image-20220227191330665

a.x = a = { n: 2 }` 的执行顺序如下:

1、先执行 a.x, 创建出x属性,此时a的指针指向的是{n:1},所以这个x属性是在{n:1}对象中的({n:1,x:}

2、然后再执行 a = { n: 2 }, 此时a的指针指向的是{n:2},而不是{n:1}

image-20220227192857390

3、把{ n: 2 }赋值给a.x,注意这个x属性是在{n:1}对象中的({n:1,x:}),所以赋值后的结果为 {n:1,x:{ n: 2 }}

image-20220227180146160

最终,根据以上的内存图中a和b的指针指向,a的指针指向的是{n:2},该对象中没有x属性,所以打印 a.xundefined,b的指针指向是 {n:1,x:{ n: 2 }},该对象中有x属性,属性值是{n:2},所以打印b.x{n: 2}

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

至此,对于以上的代码解析就结束了。

三、总结:

1、成员访问运算符类型,优先级要比 赋值运算符类型要高【重点】

a.x 优先于 a = { n: 2 } ` 执行。

2、通过画出内存图能够更加清晰的看出指针的指向关系,后续在面试的时候,可以大概画出草图方便理解。