Skip to content

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 完成深拷贝。

  1. 如果当前值不是对象,或者值为 null,直接返回原值
  2. 如果 WeakMap 中已经缓存过当前对象,直接返回缓存结果,避免循环引用导致死递归
  3. 根据当前值是数组还是对象,创建对应的空容器
  4. 先把“原对象 -> 新对象”的映射存入 WeakMap
  5. 遍历对象自身属性,递归拷贝每个字段

关键点

  • 基本类型不需要拷贝,直接返回即可
  • WeakMap 是处理循环引用的核心
  • 需要区分数组和普通对象,创建不同的初始结果
  • 当前实现主要覆盖常见对象/数组场景,像 DateMapSet、函数等特殊类型若有要求,需要额外处理
  • 时间复杂度 O(n),空间复杂度 O(n)