JavaScript中什么叫深拷貝?

在 JavaScript 中,深拷貝指的是創(chuàng)建一個新的對象,這個新的對象與原始對象完全獨立,沒有任何共享的屬性或者數(shù)據(jù),它們不共享同一塊內(nèi)存地址。深拷貝會復(fù)制原始對象的所有屬性和嵌套對象的所有屬性,包括嵌套對象中的屬性。這意味著,修改拷貝后的對象不會影響原始對象。
深拷貝是一種常見的數(shù)據(jù)復(fù)制方式,它通常用于避免在操作對象時修改原始對象。在 JavaScript 中,可以使用多種方法進行深拷貝,包括遞歸遍歷對象、lodash 的 deepClone 方法、使用 JSON 序列化和反序列化等方式。
JSON 序列化
利用 JSON 序列化和反序列化實現(xiàn)深拷貝,具體實現(xiàn)步驟如下:
- 使用
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 序列化和反序列化實現(xiàn)深拷貝存在一些局限性
- 無法復(fù)制函數(shù)、正則表達(dá)式等特殊對象類型。
- 無法復(fù)制對象的循環(huán)引用,即對象中存在自己或父對象的引用。
遞歸遍歷對象
以下是一個使用遞歸遍歷實現(xiàn)深拷貝的代碼:
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() 方法使用結(jié)構(gòu)化克隆算法創(chuàng)建給定值的深層拷貝。
結(jié)構(gòu)化克隆算法用于復(fù)制復(fù)雜 JavaScript 對象的算法。通過來自 Worker 的
postMessage()或使用IndexedDB存儲對象時在內(nèi)部使用。它通過遞歸輸入對象來構(gòu)建克隆,同時保持先前訪問過的引用的映射,以避免無限遍歷循環(huán)。
語法如下:
structuredClone(value)
structuredClone(value, { transfer })
value:被克隆的對象。可以是任何結(jié)構(gòu)化克隆支持的類型。transfer:為可選參數(shù),是一個可轉(zhuǎn)移對象的數(shù)組,里面的 值 并沒有被克隆,而是被轉(zhuǎn)移到被拷貝對象上。
返回值:返回值是原始值的深拷貝。
具體使用方法可以閱讀文章《JavaScript 中深拷貝方法structuredClone》