複製物件
1 2 3 4 5 6 7 8
| let obj1 = { food: "rice", }; let obj2 = obj1;
obj1.food = "noodle";
console.log(obj2.food);
|
在 js 裡若複製的資料型態是物件時,我們複製的其實是改物件的記憶體位置,如上例,obj2 和 obj1 都指向同一個記憶體位置,所以當改變 obj1 裡的值時,obj2 同時會被改變。
淺拷貝
為了避免這個問題,我們可以用淺拷貝的方式,也就是新建立一個物件,將原本資料全部的屬性都複製進去。
Object.assign()
1 2 3 4 5 6 7 8
| let obj1 = { food: "rice", };
let obj2 = Object.assign({}, obj1); obj1.food = "noodle";
console.log(obj2.food);
|
或是利用 es6 的展開運算子寫法
1 2 3 4 5 6 7 8
| let obj1 = { food: "rice", };
let obj2 = { ...obj1 }; obj1.food = "noodle";
console.log(obj2.food);
|
利用這個方法,可以拷貝物件裡第一層的屬性,但如果物件中屬性的值也是物件,就無法拷貝。
深拷貝
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| let obj1 = { food: "rice", flavor: ["spicy", "sweet"], fn: function () { console.log(1); }, };
let obj2 = JSON.parse(JSON.stringify(obj1)); obj1.food = "noodle"; obj1.flavor[0] = "sour";
console.log(obj2.food); console.log(obj2.flavor); console.log(obj2.fn);
|
若要連物件內的物件也拷貝,可以使用深拷貝的方法,就是將物件依序經過 JSON.stringify 及 JSON.parse 兩個方法,建立全新的物件。
上例中可以發現 obj2 經過深拷貝後,就算改動 obj1 內陣列的值,obj2 也不會被影響。
但函式無法用深層拷貝,所以 obj2.fn 是 undefined