『新手日記』Day-17 Pass by value 和 Pass by reference

wang Jeff
7 min readOct 5, 2022

每天到網路上找一張適合的照片或是當天的心情的過程居然可以變得如此開心!

今天這篇的誕生,只能用一個成語來形容:不求甚解。

如果當初有認真來看『8 天重新認識 JavaScript!』,明明在第二天的內容就有提到,但一點印象都沒有…

聽說這是個引戰題啊(誤!)...

先講結論:

要從「行為」上面來判別到底是屬於哪一種。

第一個條件用來區分到底是 pass by value 還是 pass by reference:「在函式裡對引數重新賦值,外面變數是否會改變?」

第二個條件來區分這個 pass by value 是真・pass by value 還是一個叫做 pass by sharing 的分支:「能否透過引數,改變外部變數的值」

前言

在大多數的情況下,基本型別是「傳值」,而物件型別會是「傳址」的方式,但凡事都有例外。

當初就是看到這句話才沒有認真讀,意外通常不在我考慮裡面><”

如果基本型別還不知道是什麼的可以參考這篇:

先來簡單說明一下什麼是Pass by value 和 Pass by reference

Pass by value (傳值)

當我建立2個 primitive type 的變數時(x, y),x 會在記憶體中存在一個自己的位置(假設叫做0x001)。當我指定另一個變數 y,它的值等同於 x的時候,y 實際上會建立另一個獨立的記憶體位置(假設叫做0x002),接著再把 x的值存在這個獨立的記憶體位置。也就是說, x和 y其實是存在於兩個不同的記憶體位置,因此彼此並不會乎相干擾影響。

在 JavaScript 中 primitive type(Boolean、String、 Number、 null、 undefined、symbol、bigint)都屬於 By Value。

Pass by reference

當我將變數 x設立成一個Object(或function)時,一樣在記憶體中給它一個位置(假設叫做0x001);但是當我建立一個變數 y,並且把變數 y的值等同於 x時,這時候並不會再給它一個新的位置,而是一樣指定到物件 x的位置(即0x001),因此,當 x的值改變的時候 y的值也會改變,因為它們實際上是指稱到相同的位置。

看到目前為止都很好理解吧,我當時也是這麼想的,接下來我們來看下一個範例

驚不驚喜!意不意外!

why?如果我們是用 object literal 的方式去定義 x這個變數,在這種情況底下,因為它並不清楚 x的內容是已經存在的,所以它會建立一個新的記憶體位置來存放 x物件裡面的內容。

若是使用 object literal 的方式來建立物件,則會變成 by Value,新增了一個記憶體的位置。

Pass by sharing

從前面例子發現到,雖然是Object的變數,如果是對物件變數作重新賦值,只會變更自己的值,不會連另一個變數一起變更。

這和前面提到的 Pass by reference 行為似乎不太一樣,反而有點像 Pass by value。

如此一來,稱為 Pass by reference 也不對,稱為 Pass by value 也不對,於是就出現了 Pass by sharing 的說法。

不少人將 JavaScript 的變數內容傳遞方式,稱為 Pass by sharing

  • 碰到原生型別 (Primitive),表現行為是 Pass by value。
  • 碰到物件型別 (Object),如果只是對物件內容作操作(例如陣列元素或物件屬性),表現行為是 Pass by reference。
  • 碰到物件型別 (Object),如果對物件作重新賦值,表現行為是 Pass by value。

在『技術名詞紛爭多』有這麼一段話:

程式開發的世界中,名詞的創造經常是隨意的,曾經在Java中爭執不斷的考古題之一是:「Java中有沒有Pass by reference」,就現今來說,大家公認的答案是沒有,Java只有Pass by value,不過還是有人面對Java文件中經常出現reference,而搞不清楚。

說穿了,這個名詞與C++中的reference定義不同,只不過Java最初不知道為什麼,也用了reference一詞,重點也不在搞清楚Pass by value,重點是搞清楚透過參數操作物件時,會有什麼樣的行為。

『重點其實不在這個,而是搞清楚到底參數在操作的時候會有怎樣的行為。』

你要知道 JavaScript 傳 object 進去的時候,可以更改原本物件的值,但重新賦值並不會影響到外部的 object。只要知道這一點,其他的我覺得都沒那麼重要了。

參考資料

--

--