function deepClone(obj, clonedMap = new WeakMap()) {
if (typeof obj !== 'object' || obj === null) {
return obj;
}
// 缓存避免循环引用
if (clonedMap.has(obj)) {
return clonedMap.get(obj);
}
// 正则表达式对象
if (obj instanceof RegExp) {
return new RegExp(obj);
}
// 日期对象
if (obj instanceof Date) {
return new Date(obj.getTime());
}
let clone = Array.isArray(obj) ? [] : {};
clonedMap.set(obj, clone);
// 递归拷贝
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
clone[key] = deepClone(obj[key], clonedMap);
}
}
return clone;
}
使用方法:
const obj = {
name: 'Tom',
age: 18,
hobbies: ['reading', 'music'],
friends: {
name: 'Jerry',
age: 20
}
};
const newObj = deepClone(obj);
需要注意的是,在递归拷贝对象或数组中的每一项时,需要判断该项的数据类型。如果是对象或数组,就递归调用 deepClone 函数进行深度拷贝;如果是基本数据类型,就直接赋值给新对象或数组。同时,需要注意原始数据类型和引用数据类型的拷贝方式不同。