原理:深拷貝 = 淺拷貝 + 遞迴。在淺拷貝的基礎上判斷當前屬性值是簡單型別還是引用型別。如果是簡單型別直接賦值,如果是引用型別,遞迴操作。
function isObject(obj) { // 判斷屬性值是否為引用型別
return typeof obj === 'object' && obj != null;
}
function cloneDeep(target, hash = new WeakMap()) {
if (!isObject(target)) return target;
複製程式碼
const results = Array.isArray(target) ? [] : {}; // 相容陣列型別
if (hash.has(target)) return hash.get(target); // 解決引用丟失的問題和迴圈引用的問題
hash.set(target, results);
const symkeys = Object.getOwnPropertySymbols(target); // 獲取symbol型別的鍵
if (symkeys.length) {
syskeys.forEach(item => { // 拷貝symbol型別屬性的值
if (isObject(target[item])) {
results[item] = cloneDeep(target[item], hash);複製程式碼
} else {
results[item] = target[item]
}
})
}
for (const k in target) { // 拷貝非Symbol型別屬性的值
if (Object.prototype.hasOwnproperty.call(target, k)) {
if (isObject(target[k])) {
results[k] = cloneDeep(target[k], hash);複製程式碼
} else {
results[k] = target[k];
}
}
}
return results;
}複製程式碼