J 筆記 - Clone an Object
雖然在 JavaScript 裡的物件型別是屬於 Passing by sharing,但正常來說如果沒有傳遞到另一物件的話,正常為 Passing by Address,因此沒有辦法直接用等號 =
來更改值、而會改到址。
3 Ways to Clone Objects
1 2 3 4 5 6 7 8 9 10 11 12 13
| const Array = { old: 'ES5', new: 'ES6' };
{ ...Array };
Object.assign({}, Array);
JSON.parse(JSON.stringify(Array));
|
Passing by Address
還記得 重新認識 JavaScript: Day 05 JavaScript 是「傳值」或「傳址」? 吧?基本型別的更新與傳遞會以 Passing by Value
,兩者是個是各自獨立的,而物件型別則是如同開頭所述,會更改到原本的實體,因為兩者根本是指向同一個實體的!
1 2 3 4 5 6 7 8 9
| var coin1 = { value: 10 }; var coin2 = coin1;
coin1.value = 100;
console.log( coin1.value );
console.log( coin2.value );
|
Passing by sharing
「Pass by sharing」的特點在於,當 function 的參數,如 function changeValue(obj){ ... }
中的 obj 被重新賦值的時候,外部變數的內容是不會被影響的。
1 2 3 4 5 6 7 8 9 10
| var coin1 = { value: 10 };
function changeValue(obj) { obj = { value: 123 }; }
changeValue(coin1);
console.log(coin1);
|
說了這麼多也知道了原因之後,以下就來介紹三種複製物件的方法。注意的是,Array 的複製也有探討到 深層
、淺層
的問題,如同 Deep Clone Array ㄧ樣,JSON 的方式是可以複製到 深層
的,而其他兩種沒有辦法!
- Using Spread
1 2 3 4 5 6
| const Array = { old: 'ES5', new: 'ES6' };
const SpreadCloneArray = { ...Array };
console.log(SpreadCloneArray);
|
- Using Object.assign
1 2 3 4 5 6
| const Array = { old: 'ES5', new: 'ES6' };
const Object_AssignCloneArray = Object.assign({}, Array);
console.log(Object_AssignCloneArray);
|
- Using JSON
1 2 3 4 5 6
| const Array = { old: 'ES5', new: 'ES6' };
const JSONArray = JSON.parse(JSON.stringify(Array))
console.log(JSONArray);
|
Lodash 在 deep clone 不只是適用於 Array 也同樣適用於 Object