Skip to main content

深拷贝

const _completeDeepClone = (target, map = new Map()) => {
// null 和 基本数据类型,直接返回
if (target === null) return target;
if (typeof target !== "object") return target;

// 复制一份对象的构造函数名,如果是Function|RegExp|Date|Map|Set,则生成新的实例对象
const constructor = target.constructor;
if (/^(Function|RegExp|Date|Map|Set)$/i.test(constructor.name))
return new constructor(target);

//比如对象a, a.b = a,在克隆b时,外层已经克隆了a,并设定map中有a
// 直接赋值,这样不会继续进入等号右边的a复制 b 无限循环

// 仍然是循环依赖,但是控制台巧妙处理后可以打印,不会报错
// 这种情况,深拷贝和浅拷贝没有区别,因为深层对象就是外层对象
if (map.get(target)) return map.get(target);

// 根据参数的数据类型(通过isArray)判断克隆出的类型,并设result
const cloneTarget = Array.isArray(target) ? [] : {};
// 如果获取不到,则先保存到map中,这里cloneTarget是引用类型,所以最后的操作能影响这里
map.set(target, cloneTarget);

for (prop in target) {
// 如果是target中非继承的属性
if (target.hasOwnProperty(prop)) {
// 将map传下去
cloneTarget[prop] = _completeDeepClone(target[prop], map);
}
}
return cloneTarget;
};