JavaScript中什么叫深拷貝?

在 JavaScript 中,深拷貝指的是創建一個新的對象,這個新的對象與原始對象完全獨立,沒有任何共享的屬性或者數據,它們不共享同一塊內存地址。深拷貝會復制原始對象的所有屬性和嵌套對象的所有屬性,包括嵌套對象中的屬性。這意味著,修改拷貝后的對象不會影響原始對象。
深拷貝是一種常見的數據復制方式,它通常用于避免在操作對象時修改原始對象。在 JavaScript 中,可以使用多種方法進行深拷貝,包括遞歸遍歷對象、lodash 的 deepClone 方法、使用 JSON 序列化和反序列化等方式。
JSON 序列化
利用 JSON 序列化和反序列化實現深拷貝,具體實現步驟如下:
- 使用
JSON.stringify()方法將原始對象序列化為 JSON 字符串。 - 使用
JSON.parse()方法將 JSON 字符串反序列化為新對象。
function deepClone(obj) {
return JSON.parse(JSON.stringify(obj));
}
const profile = {
name: "天行無忌",
city: "深圳",
};
const newProfile = deepClone(profile);
newProfile.city = "廣東深圳";
console.log(profile); // { name: '天行無忌', city: '深圳' }
console.log(newProfile); // { name: '天行無忌', city: '廣東深圳' }
使用 JSON 序列化和反序列化實現深拷貝存在一些局限性
- 無法復制函數、正則表達式等特殊對象類型。
- 無法復制對象的循環引用,即對象中存在自己或父對象的引用。
遞歸遍歷對象
以下是一個使用遞歸遍歷實現深拷貝的代碼:
function deepClone(obj) {
if (obj === null || typeof obj !== "object") {
return obj;
}
let result = obj.constructor();
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
result[key] = deepClone(obj[key]);
}
}
return result;
}
const profile = {
name: "天行無忌",
city: "深圳",
};
const newProfile = deepClone(profile);
newProfile.city = "廣東深圳";
console.log(profile); // { name: '天行無忌', city: '深圳' }
console.log(newProfile); // { name: '天行無忌', city: '廣東深圳' }
使用 structuredClone
原生 structuredClone() 方法使用結構化克隆算法創建給定值的深層拷貝。
結構化克隆算法用于復制復雜 JavaScript 對象的算法。通過來自 Worker 的
postMessage()或使用IndexedDB存儲對象時在內部使用。它通過遞歸輸入對象來構建克隆,同時保持先前訪問過的引用的映射,以避免無限遍歷循環。
語法如下:
structuredClone(value)
structuredClone(value, { transfer })
value:被克隆的對象。可以是任何結構化克隆支持的類型。transfer:為可選參數,是一個可轉移對象的數組,里面的 值 并沒有被克隆,而是被轉移到被拷貝對象上。
返回值:返回值是原始值的深拷貝。
具體使用方法可以閱讀文章《JavaScript 中深拷貝方法structuredClone》