连续赋值
var a = { n: 1 }
var b = a
a.x = a = { n: 2 }
console.log(a.x)
console.log(b.x)
首先,a 和 b 同时引用了{n:1}
对象
接着执行到a.x = a = {n:2}
语句,尽管赋值是从右到左的没错,但是.
的优先级比=
要高,所以这里首先执行a.x
,相当于为a(或者 b)所指向的{n:1}
对象新增了一个属性x,即此时对象将变为{n:1;x:undefined}
。
之后按正常情况,从右到左进行赋值,此时执行 a ={n:2}的时 候,a 的引用改变,指向了新对象{n:2},而 b 依然指向的是旧对象。
之后执行 a.x = {n:2}
的时候,并不会重新解析一遍 a,而是沿用最初解析 a.x
时候的 a, 也即旧对象,故此时旧对象的 x 的值为{n:2}
,旧对象为 {n:1;x:{n:2}}
,它被 b 引用着。后面输出 a.x
的时候,又要解析 a 了,此时的 a 是指向新对象的 a,而 这个新对象是没有 x 属性的,故访问时输出 undefined;而访问 b.x
的时候,将 输出旧对象的 x 的值,即{n:2}
。