當我們需要深拷貝(Deep Copy)一個object時,通常是因為我們要在不影響原始物件的情況下,對這個新的物件進行修改或擴展。
這在許多程式設計場景中都非常常見,特別是在處理配置對象、狀態管理或者在進行一些涉及到數據不可變性的操作時。同樣,在處理一些複雜數據結構的時候,深拷貝能幫助我們獲得一個完全獨立的副本,使得數據操作更加安全、靈活。
以下是使用不同方法深拷貝物件的範例,包括JSON.stringify()和JSON.parse()、structuredClone()以及Lodash的_.cloneDeep()。每個範例我都加入了console.log來輸出結果,並使用註解來說明結果值。
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
物件、Map
、Set
以及其他非序列化值。
structuredClone()
structuredClone()
方法是一種現代方式來深拷貝物件,包括它們的子物件、數組以及特殊類型的物件如Date
、Map
、Set
等。
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方法更全面的解決方案。
_.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()
方法在處理複雜物件,包括循環引用、函數和特殊物件類型時非常可靠。