淺層複製與深層複製
之前提到物件型別有傳參考的特性,但是如果想要另外修改資料,就會連帶影響原始資料內容,JavaScript 提供幾種複製方式來解決這個問題。
淺層複製 Shallow Copy
淺層複製只能複製物件的第一層,如果修改第二層資料的話,還是會影響原始資料。
for-in loop
以下範例可以發現,用 for-in
迴圈複製後的新物件會和原始資料不同。
1 | var data = { |
但是接著修改新物件後,修改第一層的內容沒有問題,不會影響原始資料,但是修改第二層後,就會連同原始物件一起修改。
1 | target.title = 'Second Level' |
Object.assign
Object.assign()
可以用來複製物件本身的屬性到另外一個目標物件上。
1 | var origin = { a: 1, b: 2, c: 3 } |
如果 目標物件 與 原始物件 的屬性名稱相同,原始物件 的屬性會覆蓋 目標物件。
1 | var origin = { a: 1, b: 2, c: 3 } |
ES6 展開語法
除了以上兩種方法,也可以用 ES6 的展開語法達到相同效果。
1 | var data = { a: 1, b: 2, c: 3 } |
深層複製 Deep Copy
淺層複製只能複製第一層資料,深層複製則是可以將資料完整複製,讓整份新複製的資料都能往下層修改,並且不會影響原始資料。
JSON.stringify
JSON.stringify()
可以將物件轉成「字串」後回傳。
重新轉成字串後再用 JSON.parse()
轉回 JavaScript 物件,如此就能達到深層複製的效果。
原理是將物件先轉成「純值」,再透過 JSON.parse()
轉回物件,此時的物件就會有一個新的記憶體空間,並且讓變數指向到新的位置。
如果物件中有 undefined、function,因為無法轉成純值,所以會直接消失,NaN 則會變成 Null
1 | var data = { |
jQuery.extend
如果要解決 undefined
、function
和 NaN
的複製問題,可以用 jQuery 的 $.extend
方法,就能做到完整的深層複製。
1 | var data = { |