JavaScript 核心觀念(27)-物件-物件參考觀念的實際運作模式
前言
前一章節講的物件傳參考觀念,其實在說明上還是很模糊,所以這一章節來實際了解運作模式吧。
純值的運作
首先先來看一下簡單的範例
1 | var a = 'Ray'; |
在上面範例中細分為兩個部分,一個是純值一個是物件,接下來我們來畫一張圖,分別代表物件與純值
在一開始 JavaScript 會先準備好兩個變數,並且先指向到 undefined
(提升的觀念,所以沒有什麼太大問題)
接下來因為 JavaScript 會準備一個記憶體空間放置我們的純值,此時 a
會指向該記憶體空間,而這個記憶體空間可能是 0x01,因此 a
其實是取得 0x01 的記憶體空間並且賦予回去而已
接下來我們會有一個行為是 var c = a;
將 a
複製到 c
,這邊要注意純值在賦予到其他變數時,是指向同一個記憶體空間並賦予值(複製一份過來)而已
1 | var a = 'Ray'; |
我相信這邊已經非常混亂了,所以我用動畫呈現了一下
因此你在修改 c
的值時,並不會影響到 a
,因為他是重新指向到另一個記憶體空間叫做 0x02
1 | var a = 'Ray'; |
這也是為什麼我們修改 c
時並不會影響到 a
,因為兩者是不同的記憶體空間。
物件傳參考
接下來講講比較難的東西,也就是物件,在物件中基本上我們看到變數後面接著 { }
就可以知道是一個物件
1 | var b = { |
並且我們也知道物件有一個東西叫做「物件傳參考」,顧名思義我們賦予到另一個變數之後病修改裡面的屬性,原有的屬性會被修改
1 | var b = { |
那這一段在記憶體空間與指向上又是怎樣呢?首先 { }
一樣會建立一個記憶體空間(undefined
那一段我就不提了)假設是 0x03 並且指向賦予回來
這一段基本上應該沒什麼問題,與純值那邊很像
但是重點是在於屬性的部分,目前屬性是一個純值概念,這些屬性都有屬於自己的記憶體空間,而 name
是只存活在這個 0x03 的記憶體空間底下的屬性,這個屬性也會指向另一個記憶體空間例如 0x04,這邊概念與純值得很像
我相信這邊指向概念已經很混亂了,所以也補上動畫圖
那麼接下來講講為什麼當我們使用 var e = b;
並且修改 name
屬性時,原有的物件會被修改,首先我們一樣會建立一個變數 e
這時候記憶體空間會指向到 b
的記憶體位置,這一段應該沒什麼太大問題
接下來重點來了,我們可以看到上方圖片我們的記憶體空間一直是指著 0x03,因此我們在操作 e.name
時,其實是操作 0x03 底下 name 屬性指向的 0x04 記憶體空間,這也就是為什麼 e.name = 'Ray'
會影響到原有的 b
物件,因為從頭到尾都是相同的指向記憶體。
1 | var b = { |
因此如果你希望建立一個新的物件空間時,請重新宣告一個物件或者賦予一個物件,這樣才不會導致物件傳參考的事情發生,因此記憶體空間都不同了。
1 | var b = { |
最後我也補一下記憶體指向的圖片與動畫
底下是動畫版的記憶體指向