ChatGpt优化后的深拷贝函数

下面是一个更为优化的深拷贝函数:

function deepClone(obj, map = new WeakMap()) {
  if (typeof obj !== 'object' || obj === null) {
    return obj;
  }

  // 如果已经遍历过该对象,则直接返回对应的克隆对象
  if (map.has(obj)) {
    return map.get(obj);
  }

  const cloned = Array.isArray(obj) ? [] : {};

  // 记录每个需要拷贝的对象和对应的克隆对象的映射关系,用于处理循环引用
  map.set(obj, cloned);

  Object.keys(obj).forEach(key => {
    cloned[key] = deepClone(obj[key], map);
  });

  return cloned;
}
const obj = { a: 1, b: { c: 2 } };
const clonedObj = deepClone(obj);
console.log(clonedObj); // { a: 1, b: { c: 2 } }

优化点如下:

  1. 添加了一个可选参数 map,用于记录每个需要拷贝的对象和对应的克隆对象的映射关系,用于处理循环引用。这里使用了 JavaScript 的弱引用 WeakMap,如果某个拷贝对象已经在该映射表中有对应的克隆对象,则直接返回该克隆对象,避免进入死循环。
  2. 使用 Object.keys 替换循环遍历对象的方式,更加简洁高效。

下面对代码的每一行进行解释:

  1. function deepClone(obj, map = new WeakMap()) { :声明一个函数 deepClone,参数为 obj 和可选参数 map,用于实现深拷贝。将 map 的初始值设置为一个空的弱映射表。
  2. if (typeof obj !== 'object' || obj === null) { return obj; }:判断 obj 是否为对象或数组,或者是否为 null,如果不是则直接返回 obj。
  3. if (map.has(obj)) { return map.get(obj); }:如果 map 中已经存在当前要拷贝的对象(即已经遍历过该对象),则直接返回对应的克隆对象,避免进入死循环。
  4. const cloned = Array.isArray(obj) ? [] : {};:声明一个变量 cloned,如果 obj 是数组则将 cloned 赋值为一个空数组,如果 obj 是对象则将 cloned 赋值为一个空对象。
  5. map.set(obj, cloned);:将当前要拷贝的对象和对应的克隆对象的映射关系记录在 map 中。
  6. Object.keys(obj).forEach(key => { cloned[key] = deepClone(obj[key], map); });:使用 Object.keys 方法获取 obj 所有可枚举属性的 key,然后遍历每个 key,对 cloned 对象的这个 key 赋值为递归调用 deepClone 函数后返回的值,并传入当前的 map 映射表。
  7. return cloned;:返回最终生成的克隆对象。

调用方式与之前相同,例如:

const obj = { a: 1, b: { c: 2 } };
const clonedObj = deepClone(obj);
console.log(clonedObj); // { a: 1, b: { c: 2 } }

猜你喜欢

转载自blog.csdn.net/weixin_46426412/article/details/130533188