8. 手写深拷贝
题目
实现一个 deepClone 函数,能够递归复制对象和数组,并处理循环引用。
代码
js
// 手写深拷贝
function deepClone(obj, map = new WeakMap()) {
if(typeof obj !== 'object' || obj === null) return obj;
if(map.has(obj)) return map.get(obj);
let res = Array.isArray(obj) ? [] : {};
map.set(obj, res);
for(let key in obj) {
if(obj.hasOwnProperty(key)) {
res[key] = deepClone(obj[key], map);
}
}
return res;
}思路
使用递归 + WeakMap 完成深拷贝。
- 如果当前值不是对象,或者值为
null,直接返回原值 - 如果
WeakMap中已经缓存过当前对象,直接返回缓存结果,避免循环引用导致死递归 - 根据当前值是数组还是对象,创建对应的空容器
- 先把“原对象 -> 新对象”的映射存入
WeakMap - 遍历对象自身属性,递归拷贝每个字段
关键点
- 基本类型不需要拷贝,直接返回即可
WeakMap是处理循环引用的核心- 需要区分数组和普通对象,创建不同的初始结果
- 当前实现主要覆盖常见对象/数组场景,像
Date、Map、Set、函数等特殊类型若有要求,需要额外处理 - 时间复杂度
,空间复杂度