Skip to main content

实现深拷贝

深拷贝注意点
  • 注意类型,6种基本类型: booleanstringnumberundefinednullSymbol
  • Object类型的可能情况(Object.prototype.toString.call):
    • [object Object]
    • [object Function] (可以用 typeof function == function 判断)
    • [object Null]
    • [object Array]
    • [object RegExp]

解法

function deepCopy(data, hash=new WeakMap()){
if(typeof data !== 'object' || data == null){
return data;
}

// 判断传入的待拷贝对象是否已经存在hash中,避免循环引用造成死循环
// 另外,使用WeakMap,有利于垃圾回收
if(hash.has(data)){
return hash.get(data);
}

const newData = Array.isArray(data) ? [] : {};
const dataKeys = Object.keys(data);
dataKeys.forEach(key => {
const current = data[key];
const typeString = Object.prototype.toString.call(current).toLowerCase();

if(typeof current !== 'object' || current == null){
// 基本类型则不需要特殊处理
newData[key] = current;
return;
}

switch(typeString){
case '[object array]':
newData[key] = [...deepCopy(current, hash)];
break;
case '[object set]':
newData[key] = new Set([...current.values()]);
break;
case '[object map]':
newData[key] = new Map([...current]);
break;
default:
// 普通对象进行递归操作
hash.set(data, data);
newData[key] = deepCopy(current, hash);
}
})

return newData;
}