今天突发奇想,取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, 表示循环引用处理正确