以下代碼輸出什么? 為什么?
var a = {n:1}; var b = a; a = {n:2}; a.x = a ; console.log(a.x); console.log(b.x);
var a = {n: 1} var b = a; a.x = a = {n: 2}; console.log(a.x); console.log(b.x)
第一個問題:
a.x ---> {n:2,x:a}; b.x ---> undefined;
解答:a的值很清晰了,a第二次賦值以后變成了{n:2},隨后添加了x屬性指向自身。而對於b,在a第二次賦值以后,由於js中給變量賦值為object類型時,變量中存儲的是對這個object的引用。
此時,a指向{n:2} ,而b指向了{n:1} ,a和b指向不同的對象,因此,在a上添加屬性對於b無影響,b.x自然就是undefined。
第二個問題:
解答:第三句里的主要難點在js運算符的優先級,訪問屬性、調用方法運算符"."的優先級高於賦值運算符。因此執行順序是
- 給a添加屬性x,此時a,b都是 { n:1,x:undefined },a.x 運算后的結果即為這個object(可以說也就是b)的x屬性值。
- 把{n:2}賦值給a,此時a是 {n:2},是一個新的對象。 b是{ n:1,x:undefined }。
由於( . 運算符最先計算)一開始js已經先計算了a.x,便已經解析了這個a.x是對象A的x,所以在同一條公式的情況下再回來給a.x賦值,也不會說重新解析這個a.x為對象B的x。
所以 a.x=a 應理解為對象A的屬性x指向了對象B:
(這個時候a.x 已經運算完了,不會再與a產生任何關系,a.x依舊代表那個n為1對象的x屬性值,和a已經沒關系了。) - 把{n:2}賦值給a.x 也就是 { n:1,x:undefined }這個對象的x屬性,這個時候b依舊指向這個object,因此此時,a是{n:2},b是{n:1,x:{n:2}}