一、面试题介绍
面试题代码如下:
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 }
var a = { n: 1 }
var b = a
创建一个b对象,并把a赋值给b,此时a和b的指针指向相同,都指向{ n: 1 }
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/…
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}
3、把{ n: 2 }
赋值给a.x
,注意这个x
属性是在{n:1}
对象中的({n:1,x:}
),所以赋值后的结果为 {n:1,x:{ n: 2 }}
最终,根据以上的内存图中a和b的指针指向,a的指针指向的是{n:2}
,该对象中没有x属性,所以打印 a.x
为 undefined
,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、通过画出内存图能够更加清晰的看出指针的指向关系,后续在面试的时候,可以大概画出草图方便理解。