思路
- 处理基本数据类型,直接返回。
- 对于函数,直接返回原函数(因为函数在深拷贝时通常不希望克隆新的实例,而是保持引用一致)。
- 对于正则表达式,创建新的正则表达式实例。
- 对于日期对象,创建新的日期对象并传入原日期对象的值。
- 对于数组和对象,创建新的数组或对象,并递归地对其属性进行深拷贝。在递归过程中,要处理循环引用,通过一个Map来记录已经拷贝过的对象,避免无限递归。
代码实现
function deepClone(obj, map = new Map()) {
if (obj === null || typeof obj !== 'object') {
return obj;
}
if (obj instanceof Function) {
return obj;
}
if (obj instanceof RegExp) {
return new RegExp(obj.source, obj.flags);
}
if (obj instanceof Date) {
return new Date(obj.getTime());
}
if (map.has(obj)) {
return map.get(obj);
}
let clone;
if (Array.isArray(obj)) {
clone = [];
for (let i = 0; i < obj.length; i++) {
clone[i] = deepClone(obj[i], map);
}
} else {
clone = {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
clone[key] = deepClone(obj[key], map);
}
}
}
map.set(obj, clone);
return clone;
}