这个深拷贝,有效吗,请各位指教一下

35 阅读1分钟

今天突发奇想,取GPT上生成了一下深拷贝的写法,发现这个这个深拷贝是不是挺全面的,性能怎么样。还有有哪里不对吗,推荐使用吗

function deepCopy(obj, hash = new WeakMap()) {
  if (
    !(obj !== null && (typeof obj === "function" || typeof obj === "object"))
  ) {
    return obj;
  }

  // 避免循环引用
  if (hash.has(obj)) {
    return hash.get(obj);
  }

  let copy;

  const objType = Object.prototype.toString.call(obj);

  switch (objType) {
    case "[object Object]":
      copy = {};
      hash.set(obj, copy);
      Reflect.ownKeys(obj).forEach((item) => {
        copy[item] = deepCopy(obj[item], hash);
      });
      break;
    case "[object Array]":
      copy = [];
      hash.set(obj, copy);
      obj.forEach((item) => {
        copy.push(deepCopy(item, hash));
      });
      break;
    case "[object Map]":
      copy = new Map();
      hash.set(obj, copy);
      obj.forEach((item, key) => {
        copy.set(key, deepCopy(item, hash));
      });
      break;
    case "[object Set]":
      copy = new Set();
      hash.set(obj, copy);
      obj.forEach((item) => {
        copy.add(deepCopy(item, hash));
      });
      break;
    case "[object Function]":
      copy = obj.bind(this);
      break;
    case "[object Date]":
      copy = new Date(obj.getTime());
      break;
    case "[object Symbol]":
      copy = Symbol(obj.description);
      break;
    case "[object RegExp]":
      copy = new RegExp(obj.source, obj.flags);
      break;

    case "[object Error]":
      copy = new obj.constructor(obj.message);
      copy.stack = obj.stack;
      break;
    default:
      throw new Error(`Unsupported type: ${objType}`);
  }

  return copy;
}

// 测试
const obj = {
  a: 1,
  b: ["x", "y", { c: 3 }],
  c: new Set([1, 2, 3]),
  d: new Map([
    ["key1", "value1"],
    ["key2", "value2"],
  ]),
  e: new Date(),
  f: /abc/g,
  g: new Error("An error"),
  h: function () {
    return "hello";
  },
  i: null,
  j: Symbol(99),
};

obj.self = obj; // 循环引用

const clone = deepCopy(obj);

console.log(clone);
console.log(clone.self === clone); // true, 表示循环引用处理正确