物件傳參考
JavaScript 中,資料的傳遞分為兩種方式:
- 傳值:Call by value 或 Pass by value
- 傳址(傳參考):Call by reference 或 Pass by reference
傳值
JavaScript 中除了物件型別以外都是基本型別,基本型別就是單純的值。
而基本型別是透過「傳值」的方式傳遞資料:
- Boolean:布林
- Null:空值
- Undefined:未定義
- Number:數字
- String:字串
假設今天 a
的值是 10,b
又等於 a
,如果把 a
重新賦值 100,那 b
的結果會是什麼呢?
1 | var a = 10 |
答案是:10。
在電腦裡的世界,可以想像成一個個空間,有 記憶體位置 的空間,也有 儲存值 的空間。
為了方便取用,才有變數的存在,再用變數連結(指向)這些記憶體位置。
而宣告變數賦值,就是把變數的值存進電腦裡專門存值的空間。
所以在傳值的概念裡,兩個變數分別儲存在不同空間,就算其中變數 a
重新賦值,也不會影響原本複製過去的變數 b
。
傳址
除了基本型別外,其他型別都算物件型別。
物件的定義需要包含 key
和 value
,會以「傳址(傳參考)」的方式傳遞資料:
- Object:物件
- Array:陣列
- Function:函式
以下方範例為例,變數 a
、b
分別是什麼呢?
1 | var a = { x: 1 } |
答案是:a = { x: 2, y: 3 }
,b = { x: 2, y: 3 }
因為物件是「傳址」,所以並不會重新賦值,當然也就不會準備新的儲存空間,只會指向原本的位置。當變數的值改變時,原本位置的值也會跟著改變。
1 | var a = { x: 1 } // 儲存值 (1) |
再以下方範例為例:
如果用等號再對變數 b
重新賦值,再宣告一個變數 c
指向 b
。
請問變數 a
、b
、c
分別是什麼呢?
1 | var a = { x: 1 } |
答案是:a = { x: 1, y: 3 }
,b = { x: 1, y: 3 }
,c = { x: 2 }
雖然有準備新的空間給變數 b
,並且讓 c
指向 b
,但是後來又把 b
指向 a
,c
指向的是 b
原本的記憶體位置,所以當變數 a
的內容改變,b
的值也會一起改變。
1 | var a = { x: 1 } // 儲存值 (1) |