# 物件傳參考|筆記 by Sz ###### tags: `Sz` `課前` `Vue新手夏令營` - [Vue 新手夏令營 課程頁面](https://hackmd.io/@dbFY0UD9SUeKmNXhWf01ew/BkJoW-hn_/%2FC05go-8iTSS-nrMwKU22kA) - [:sun_with_face:筆記入口](/2JiZbCPdR0G4p5fNycPmTg) > ### 備註 > 找資料的時候看到很多種說法,可能要留意一下是不是在講同件事XD > 傳參照、傳參、call by reference、pass by reference ## 傳?傳什麼? - [五分鐘快速了解 [傳址,傳參考,傳址] ](https://ithelp.ithome.com.tw/articles/10198215) - [JS 的傳值 & 傳參考](https://ithelp.ithome.com.tw/articles/10225762) - [這篇還沒看](https://ithelp.ithome.com.tw/articles/10209104) ### 參考是什麼? 參考(參照、reference) ,指的是他們存在的記憶體空間 傳參考會共用同一個記憶體空間,不會複製 ### JS 的傳值與傳參考 #### 傳值 Call By Value - 把 value 傳到另一個**記憶體位置**的 value 上,是 copy 非 link - JS 中的純值就是這個特性(Boolean、Null、Undefined、Number、String) - 彼此只有 copy 關係,所以 copy 完後,其中一方被更改,不會影響到另一方 #### 傳參考 Call By Reference - 把記憶位置傳到另一個物件的記憶體位置上,為 link 非 copy - JS 中物件型別(這個詞不太懂,包含 function, array)是這個特性 - 彼此有 link 關係,所以在哪裡其中一方被修改了,兩邊都會更新 ## Object 的傳參考特性 不論物件、陣列都是用傳參考方式賦值, 賦值後彼此有 link 關係,其中一方被更改,兩方都會一起更新 有個 person 物件 ``` const person = { name: '小明', obj: {} } ``` person2 與 person 建立了一個 link 關係 在 person2 裡不論更改 key, 或是內部 obj 的 key 都會更新原本資料 ``` const person2 = person; // link 了一個 person2 物件 person2.name = '杰倫'; // 在 person2 更新這個物件內容 person.name = person2.name = '杰倫'; // 兩邊都會自動更新 ``` ### object 在 object 內部也一樣擁有傳參考特性 再額外建立一個 obj2 跟 obj 建立 link 關係(還不知道為什麼要這麼做) 直接打 person2.obj.{key} 也會更新 person.obj ``` const obj2 = obj // 建立新的 link ``` ## Danger Zone ### 透過 function 修改 object 的 key (不清楚自己在幹嘛不要亂用) 有個 funciton 專門修改 object 的某個 key ``` const fn = (item) => { item.name = '杰倫'; } ``` 不論這個 function 帶入 person, person2 都會被更新 ``` fn(person2); // 透過這個 function 去修改 person2(跟 person 有 link 相關) console.log(person); // 物件傳參考特性, person 也會被更新 ``` ## 斬斷一切的牽連:淺層拷貝、深層拷貝 開發時如果沒有留意到傳參考特性,會很容易不小心修改到原本的資料 避免此狀況可使用 ### 淺層拷貝(Shallow Copy) 最外層的 object 是新建的,內層若有其他 object 還是保留傳參考特性,程式碼較單純 #### Object.assign() ``` const newObject = Object.assign({}, originObject) ``` - 第一個 parameter 放空的 object (建立新的記憶體空間) - 第二個放想要複製的 object - 在空 object 中展開想要複製的物件 #### 在新的空 object 內展開 ``` const newObject2 = { ...originObject } ``` ### 深層拷貝(Deep Copy) 將轉為字串再轉回 object 的 object 賦值在 newObject 上 兩者已經沒有關係了 ``` const newObject = JSON.parse(JSON.stringify(object)) ```