深拷贝?循环引用?

184 阅读1分钟

使用WeakMap避免循环引用。这个实现使用了递归来深度拷贝对象,同时利用 WeakMap 来处理循环引用。当递归访问到一个对象时,将它存入 WeakMap,如果后面再次访问到相同的对象,直接从 WeakMap 中获取,避免陷入无限递归。

需要注意的是,这里使用了 hasOwnProperty 来确保只拷贝对象自身的属性,而不包括原型链上的属性。这是为了防止深拷贝时无限递归遍历原型链。

function deepClone(obj, cache = new WeakMap()) {
  // 判断是否为基本数据类型,如果是直接返回
  if (obj === null || typeof obj !== 'object') {
    return obj;
  }

  // 检查缓存中是否已经存在该对象,如果是循环引用则直接返回缓存中的对象
  if (cache.has(obj)) {
    return cache.get(obj);
  }

  // 创建一个新对象,用于存储拷贝的结果
  const newObj = Array.isArray(obj) ? [] : {};

  // 将当前对象存入缓存
  cache.set(obj, newObj);

  // 遍历对象的所有属性,递归进行深拷贝
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      newObj[key] = deepClone(obj[key], cache);
    }
  }

  return newObj;
}

// 示例用法
const obj = {
  a: 1,
  b: {
    c: 2,
    d: [3, 4],
  },
};

// 添加循环引用
obj.e = obj;

const clonedObj = deepClone(obj);
console.log(clonedObj);