var a = {n: 1}; var b = a; a.x = a = {n: 2}; console.log(a.x); console.log(b.x);
有道題是這樣的,覺得很奇葩,分析一下
1.對象 引用類型
對象屬於引用類型,c,java,js里面都是的,對象就是引用類型,包括數組。
上面的a是引用類型,a保存的是對象 {n: 1}的地址,對這個對象的引用。b = a 。把a里面的地址賦值給了b,b也指向{n: 1}這個對象的物理地址。所以,a 一旦做賦值更改,修改的是a對引用的修改。b也同時修改,b修改的時候,a也會被修改。這就是引用類型。
堆和棧。堆是真實的{n:1} 。棧里面存放的是堆的物理地址,值比較小。根據棧的地址去找堆里面的數據。
2.
var a = {n:1}; var b = a; a.x = a = {n:2}; console.log(a===b.x); //true
第二個奇葩結果
3.
https://blog.csdn.net/qiphon3650/article/details/78860973
我把這篇看了,然后覺得還是不理解
就這句: 執行a.x=a,此時a已經指向了新對象,而a.x因為在執行前保留了原引用。
不理解的點是 a都已經改變指向了,a指向了{n: 2},a.x里面的a的指向當然也改變成了{n: 2},為什么,a.x還會保留原引用
4.我又看了別人寫的,覺得這樣比較好繞回來
a.x的運算優先級最高
也就是說
var a = {n:1}; var b = a; a.x = a = {n:2}; console.log(a===b.x); //true
這段代碼可以寫成這樣
var a = {n:1}; var b = a; a.x = (a = {n:2}); console.log(a===b.x); //true
這樣就解釋通了
1.a指向 {n: 1}; ---> var a = {n: 1};
2.b指向 a指向的這個 {n: 1} ---> var b = a;
3.計算 a.x = (a = {n: 2}); a.x的值是 后面值的結果,后面的值先不管。此時 a.x = (某個值),是先計算的。a.x 這個a 指向並沒有被 改變
所以. a.x 里面的a仍然是原來的 {n: 1};a.x里面的值是后面( a = {n: 2})這個結果的返回值。這個返回值是 {n: 2};
4.所以拆分成a.x = { n: 2 }; 然后原來的a的值被 a = {n: 2},b是對原來對象的引用; a 最后賦值的結果是a = {n: 2};
所以。a.x是underfined,因為新的a里面並沒有 x這個屬性
所以我覺得這個賦值運算的結果,a = {n: 2}這個a並沒有更改引用的時候,它的返回值就已經確定了,就先賦值給原來的a.x里面的a了。我只是猜想。。。連等式可能並不會去計算過程,其中所有的值都直接被最后一個等號的值給賦值,其中,引用類型的賦值. 會優先賦值計算。
這個圖表示最后的結果,並不能表示賦值過程。