[JS奇怪的世界]No.28 觀念小叮嚀:傳值和傳參考
前言
我們即將深入瞭解 JavaScript 中其中一個很常遇到的東西,傳值 (by value) 及傳參考 (by reference),這個觀念很重要,所以若對於這觀念不清楚,將會導致後續開發上及 debug 上的困擾。
傳值 (by value)
傳值其實很簡單,讓我們從範例來了解 ↓
1 | var a = 2; |
b
會去尋找 a
的記憶體位址,然後複製填上相同的值到 b
並得到新的記憶體位址,而這個過程就是傳值 (by value)
傳參考 (by reference)
這邊要講的這個東西就比較常見了,如果在 JavaScript 中有一個物件,當設定變數為一個物件一樣可以取的一個記憶體位址,但當 b
等於 a
的意思其實是我們試著讓這兩個東西一樣,所以 b
並不會得到新的記憶體位址,而這就是傳參考 (by reference)。
所有物件都是傳參考 (by reference)特性。
範例傳值 (by value)
這邊先來看看傳值 (by value) 的範例 ↓
1 | var a = 3; |
這邊要記得一個重點,只要不是物件,那就是在傳值 (by value) 因為 3
是一個純值一個數值,所以 b
會 copy a
的值並且建立一個新記憶體位址,所以若我們這樣做並不會影響到 b
↓
1 | var a = 3; |
而這就是所謂的**傳值 (by value)**。
範例傳參考 (by reference)
首先先準備一個物件範例 ↓
1 | var c = { greeting: 'hi' }; |
當執行程式碼時會發生什麼事情?d
會知道它後面帶入的是一個物件 (Object),所以並不會建立新的記憶體位址,而是直接讓 d
指向與 c
相同的記憶體位址,雖然輸出時可以看到相同的東西,但是在記憶體指向是相同的,所以如果這樣做 ↓
1 | var c = { greeting: 'hi' }; |
我們可以看到 d
也跟著變了。
這就是所謂的傳參考 (by reference,而 c.greeting = 'hello';
這過程稱之為 mutate。
所以當等號運算子知道你要改變某個值的時候,它就會去改變 (mutate)。
mutate 就是改變某個東西的意思,當我們說 I mutate my object,就是代表著我要改變它 (Object),所以我們可以知道一件事情,不論我們在哪一行做修改,都會導致 d
被改變,原因是它們都是指向同一個記憶體。
例外狀況
這邊還需要知道一件事情,等號運算子可以設定一個新記憶體空間,當若我們是使用這種方式去修改的話 ↓
1 | var c = { greeting: 'hi' }; |
這樣做 d
和 c
就不會指向同一個記憶體位子,那這是一個特殊狀況。