一、實現原理
1. 對象類型的深拷貝
function deepClone(source, map = new Map()) {
if (source === null || typeof source !== "object") {
return source;
}
if (map.get(source)) {
return map.get(source);
}
let target = Array.isArray(source) ? [] : {};
map.set(source, target);
Object.keys(source).forEach(key => {
if (source.hasOwnProperty(key)) {
target[key] = deepClone(source[key], map);
}
});
return target;
}
2. 基本數據類型的深拷貝
function deepClone(data) {
return JSON.parse(JSON.stringify(data));
}
以上代碼中出現了一個新的概念:Map,它的用途是用來記錄已經拷貝過的對象,避免重複拷貝。
二、應用場景
1. 場景一:對象中的數據飽含了業務邏輯,需要對其進行深度拷貝。
例如,業務中有一個 order 對象,它包含了訂單信息、購物車信息等,這個對象的數據量很大,而且其中的對象結構非常複雜,如果使用淺拷貝,可能會只獲取到其中的部分數據,而導致業務出現問題。這時就需要使用深拷貝。
2. 場景二:函數中參數傳遞的時候,需要對複雜對象進行拷貝,避免原始對象被修改,影響其他業務邏輯。
假設在一個項目中,有一個函數需要接收一個對象作為參數,而這個對象可能被多個其他函數調用,如果這個對象是一個被掛載在全局變量上的單例對象,那麼很可能在調用函數的過程中被其他函數改變,從而導致程序失去控制。這時就可以在函數中使用深拷貝,每次將數據進行拷貝,避免了原始對象被修改的情況。
三、深拷貝的缺點和注意事項
1. 深拷貝會消耗大量的內存空間和運算時間,當數據量過大的時候,可能會導致性能問題。
2. 如果拷貝對象包含遞歸引用,例如 A 對象中的某個屬性引用了 A 對象本身,那麼拷貝函數會陷入無限遞歸的死循環,導致瀏覽器或者 Node.js 服務器崩潰。
3. 對於一些不可拷貝的數據類型,例如函數、正則表達式、Promise 等,需要特殊處理。
四、總結
ES6中的深拷貝是基於遞歸和 Map 數據結構實現的,可以在複雜數據類型的業務場景中避免出現因為淺拷貝而導致的數據不完整或失真的情況。在實際應用中,需要根據業務情況來選擇使用深拷貝或淺拷貝,並且需要避免濫用深拷貝,以免導致性能問題。
原創文章,作者:WHUI,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/149073.html