网上看到“叶小钗”的一篇面试文章,里面谈到了一个js的面试题,本身作着试了下,全错!因而根据结果,反推了下缘由。html
题目:java
var a = {n: 1};var b = a; a.x = a = {n: 2} console.log(a.x); console.log(b.x)
这里面至少考了2个点:面试
一、js的引用类型数据;spa
二、运算符优先级;code
对于一个老手来讲,这里的坑主要在第二条,运算符优先级。htm
a.x = a = {n: 2}
2个等号,优先级相同,就先来后到,从左到右,等效于blog
a.x={n:2}; a={n:2};
为何不能等效于:get
a.x=a; a={n:2};
我的这么分析:console
js在执行赋值语句时,class
若是等号右边是单个变量或者常量,直接执行赋值语句
若是是表达式,就看运算符优先级,若是优先级高于赋值语句,好比加法、减法等,就等高优先级运算以后,将结果赋值
若是又是一个赋值语句,那么优先级并不比本身高,就不能让它先计算,而是本身先往右继续寻找,直到找到一个独立的常量或者变量。
在这个例子中
a.x = a = {n: 2}
js引擎,不会把a直接赋值给a.x,由于a不是独立的,它从属于另一个赋值语句,且是它的主体
a = {n: 2}
这个赋值语句,计算优先级和本身相同,先来后到,那么这个赋值语句就不能执行,本身仍是继续往右找:a不能赋值,=是运算符,更不可能,继续往右,就是
{n: 2}
它是一个正真独立的常量,因此第一个等号就赋值成它,也就是
a.x={n:2};
的出处,执行完第一个赋值语句,再执行第二个
a = {n: 2}
第二个比较直接就没什么好说的了
因此,源代码中
a.x = a = {n: 2}
改为
a.x = (a = {n: 2})
运算结果也仍是不变