S
Shih, Cheng-Fu2 個月前

如何複製一個object並不影響原始object?


當我們需要深拷貝(Deep Copy)一個object時,通常是因為我們要在不影響原始物件的情況下,對這個新的物件進行修改或擴展。

這在許多程式設計場景中都非常常見,特別是在處理配置對象、狀態管理或者在進行一些涉及到數據不可變性的操作時。同樣,在處理一些複雜數據結構的時候,深拷貝能幫助我們獲得一個完全獨立的副本,使得數據操作更加安全、靈活。

以下是使用不同方法深拷貝物件的範例,包括JSON.stringify()和JSON.parse()、structuredClone()以及Lodash的_.cloneDeep()。每個範例我都加入了console.log來輸出結果,並使用註解來說明結果值。

1. 使用 JSON.stringify()JSON.parse()

這個方法將物件序列化為JSON字符串,然後再解析回新物件。它是快速且簡單的深拷貝方法,但只適用於包含可序列化數據的物件。

let obj = {
    A: 1,
    B: {
        a: '2-1',
        b: '2-2'
    },
    C: {
        a: '3-1',
        b: '3-2'
    }
};
let newObj = JSON.parse(JSON.stringify(obj));

newObj.C.b = "3-22222";
newObj.A = 2;

console.log(obj.A); // result: 1
console.log(obj.C.b); // result: "3-2"

限制:不支持函數、Date物件、RegExp物件、MapSet以及其他非序列化值。

2. structuredClone()

structuredClone()方法是一種現代方式來深拷貝物件,包括它們的子物件、數組以及特殊類型的物件如DateMapSet等。

let obj = {
    A: 1,
    B: {
        a: '2-1',
        b: '2-2'
    },
    C: {
        a: '3-1',
        b: '3-2',
        d: new Date() // `structuredClone`可以處理Date和其他類型
    }
};
let newObj = structuredClone(obj);

newObj.C.b = "3-22222";
newObj.A = 2;

console.log(obj.A); // result: 1
console.log(obj.C.b); // result: "3-2"

優點:支持廣泛的內建類型,提供比JSON方法更全面的解決方案。

3. 使用 Lodash 的 _.cloneDeep()

Lodash 提供了一個實用函數_.cloneDeep() 來深拷貝物件,它可以處理複雜的數據類型和循環引用。

let _ = require('lodash');

let obj = {
    A: 1,
    B: {
        a: '2-1',
        b: '2-2'
    },
    C: {
        a: '3-1',
        b: '3-2'
    }
};
let newObj = _.cloneDeep(obj);

newObj.C.b = "3-22222";
newObj.A = 2;

console.log(obj.A); // result: 1
console.log(obj.C.b); // result: "3-2"

優點:Lodash的_.cloneDeep()方法在處理複雜物件,包括循環引用、函數和特殊物件類型時非常可靠。


圖片
圖片
圖片
圖片
圖片
圖片
(使用 Facebook 留言外掛程式 留言無法滿足本網站參加活動之資格,僅供非會員討論使用)
互動地圖
interactive taiwan map