之前遊戲設計師的面試有問到這題, 理解清楚說不定會更好,順便給自己看
參考城市碼農大大
原文如下 :
正文開始 : ----------------------------------------------------------------------------------------
JS淺拷貝 : JS在Object資料類型底下會遵循Call by Reference,
那假設有兩個物件,物件a和物件b都指向相同地址,
只要修改物件b的值,也會連帶對應到物件a的地址,那麼物件a的值也會一起受到改變,因此物件a跟b會互相影響。
當 Original Object data 與 Cloned Object data ,是兩個完全獨立,每一層的資料地址都不同,相互不影響的深層物件,就為深拷貝(deep copy)。
一、JSON.stringify/parse
JSON.stringify/parse 常見於處理 Local Storge、Session Storage 等 Storage 的儲存操作,其實也可以用來實踐深拷貝。
主要是用 JSON.stringify 先把物件轉字串,再用 JSON.parse 把字串轉物件即可。
我的說法 : 用,Json.stringfy 把物件轉字串,再反過來將字串轉物件,就可以
/*** 深拷貝:JSON.stringify/parse ***/
const originalData = {
firstLayerNum: 10,
obj: {
secondLayerNum: 100,
},
};
const clonedData = JSON.parse(JSON.stringify(originalData));
clonedData.firstLayerNum = 20;
clonedData.obj.secondLayerNum = 200;
console.log(originalData.firstLayerNum);
// 10 => 第一層「沒有」被 clonedData 影響
console.log(originalData.obj.secondLayerNum);
// 100 => 第二層「沒有」被 clonedData 影響
但需要特別注意有些值經過 JSON.stringify/parse 處理後,會產生變化,導致非預期的結果發生:
- undefined : 會連同 key 一起消失。
- NaN : 會被轉成 null。
- Infinity :會被轉成 null。
- regExp : 會被轉乘 空 {}。
- Date : 型別會由 Data 轉成 string。
用Loadash library 本身會提供深拷貝 cloneDeep() 的方法, 且不會遇到 JSON.stringify/parse 部分值會非預期改變的問題
淺深拷貝總結
用一張圖簡易地總結淺深拷貝的概念: