在實作時常會聽到 call by reference 還是 call by value,這兩個有什麼不同?最簡易的解釋方法是:
call by reference : 呼叫變數的記憶體位置
call by value : 呼叫變數的值
事實上除了這兩種,還有一種叫 call by Sharing,在傳遞參數時會用到,之後再來介紹。
JavaScript 的資料型別分成原始型別(primitive values)和物件型別(Object),詳細型別可看此篇:JavaScript 基礎 型別篇
Object(物件): Object, Array
Objet 和 Array 在 Javascript 屬於複合型(composite)或參考型(reference)的原始資料類型,
在呼叫、複製或傳參數的時候,是參考記憶體的位置而不是值,這點要特別注意。
複製資料的時候
複製資料的時候 是用 By valur 或是 By reference 呢?
By valur
1 | var a = 'something'; |
a 和 b 如期的印出我們賦予的值。我們可成功無誤的修改 b 的值。
Primitive type(基本型別):Number, String, Boolean, Null, Undefined
By reference(參考值)
1 | const person = { |
上面的範例在修改 person2 這個 object 裡的 name 屬性時,也會同時改到原來參考的 person 的 name 屬性,是不是很恐怖?
1 | // 陣列 |
因為 Array 也是參考型(reference)的原始資料類型所以也會像 Object 一樣,在修改時也會更改到原始參考值 by reference。
如何複製一個物件而不要更動到參考值?以下是方法:
1 | let person = { |
方法一 使用 assign:先給一個空{} 來裝複製過來的物件
1 | let person2 = Object.saaign({}, person); |
方法二 使用 JSON 文字化
1 | var person2 = JSON.parse(JSON.stringify(person)); |
JSON.stringify(); 是文字化、JSON.parse(); 是解析文字,兩函式處理下來等於複製了一份 person 到 person2
使用 Object.assign()處理 object 的缺點
如果遇上多層結構的 Object,就無法使用 assign()來處理,因為它只能處理一層的結構而無法處理兩層,也就是說這種方法只能用在 Array 上。在第二層裡的原始資料仍然會被更動到。
1 | var person = { |
function 也是一種特殊的 Object 資料型別。
參考:小龜前輩:參數傳遞方式