深拷贝函数的实现

使用JSON.parse(Json.stringify())实现深拷贝有哪些坑?

  • 如果属性值是undefined、或者函数,序列化后属性丢失;
  • 如果属性值是RegExp、Error对象,序列化后值是{};
  • 如果属性值是NaN、Infinity和-Infinity,则序列化的结果会变成null

因此一般都采用自定义函数实现:

function deepClone(obj, hash = new WeakMap()) {
    // 处理 null、undefined、非对象的情况(直接返回值)
    if (obj === null || typeof obj !== 'object') return obj;

    // 防止循环引用
    if (hash.has(obj)) return hash.get(obj);

    // 支持 Date、RegExp 类型
    if (obj instanceof Date) return new Date(obj);
    if (obj instanceof RegExp) return new RegExp(obj);

    // 创建对象或数组的副本
    const clone = Array.isArray(obj) ? [] : {};
    hash.set(obj, clone);

    // 递归拷贝每一个属性
    for (const key in obj) {
        if (obj.hasOwnProperty(key)) {
            clone[key] = deepClone(obj[key], hash);
        }
    }

    return clone;
}

解释

  1. 类型判断:对于 nullundefined 和非对象类型直接返回。
  2. 循环引用:使用 WeakMap 防止循环引用导致的无限递归。
  3. 特殊对象处理DateRegExp 类型分别创建新的实例。
  4. 递归拷贝:对于每个属性,递归调用 deepClone,实现深度复制。
posted @ 2024-11-11 11:48  我是格鲁特  阅读(5)  评论(0编辑  收藏  举报