当前位置: 首页 > article >正文

深拷贝实现方法

先写一个最简单的深拷贝函数

function deepClone(obj) {
  // 如果是基本数据类型或 null,直接返回
  if (obj === null || typeof obj !== 'object') {
    return obj;
  }

  // 如果是数组
  if (Array.isArray(obj)) {
    const arrCopy = [];
    for (let i = 0; i < obj.length; i++) {
      arrCopy[i] = deepClone(obj[i]);
    }
    return arrCopy;
  }

  // 如果是对象
  const objCopy = {};
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      objCopy[key] = deepClone(obj[key]);
    }
  }

  return objCopy;
}

// 测试
const original = {
  a: 1,
  b: [2, 3, { d: 4 }],
  c: { e: 5 }
};

const copied = deepClone(original);
console.log(copied);

这里面看似没啥毛病,但是来了,如果对象中存在自身引用(即对象内部某个属性指向对象本身),那么普通的递归深拷贝就会进入无限循环,导致栈溢出。
为了解决这个问题,我们可以使用一个辅助对象来追踪已经拷贝过的对象,并在遇到相同的引用时直接返回已拷贝的对象。下面是改进版的深拷贝函数,能够处理自身引用的情况:

function deepClone(obj, map = new WeakMap()) {
  // 如果是基本数据类型或 null,直接返回
  if (obj === null || typeof obj !== 'object') {
    return obj;
  }

  // 如果已经拷贝过这个对象,直接返回
  if (map.has(obj)) {
    return map.get(obj);
  }

  // 如果是数组
  if (Array.isArray(obj)) {
    const arrCopy = [];
    map.set(obj, arrCopy);  // 记录这个数组
    for (let i = 0; i < obj.length; i++) {
      arrCopy[i] = deepClone(obj[i], map);
    }
    return arrCopy;
  }

  // 如果是对象
  const objCopy = {};
  map.set(obj, objCopy);  // 记录这个对象
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      objCopy[key] = deepClone(obj[key], map);
    }
  }

  return objCopy;
}

// 测试自身引用
const obj = {};
obj.self = obj;  // 自身引用

const copiedObj = deepClone(obj);
console.log(copiedObj);  // 输出: { self: [Circular] }


http://www.kler.cn/a/545950.html

相关文章:

  • 缓存三大问题及其解决方案
  • 第1章大型互联网公司的基础架构——1.5 服务发现
  • STM32HAL库快速入门教程——常用外设学习(2)
  • nginx播放视频(auth_request鉴权)
  • Unity3D 类MOBA角色控制器 开箱即用
  • 调用DeepSeek API接口:实现智能数据挖掘与分析
  • 腾讯发布混元-3D 2.0: 首个开源高质3D-DiT生成大模型
  • 机器视觉--Halcon变量的创建与赋值
  • 【ICP/EDI教程】增值电信年报网络信息安全表存档记录 申请的时候对着抄
  • 两步在 Vite 中配置 Tailwindcss
  • 【git-hub项目:YOLOs-CPP】本地实现02:跑通项目了
  • Humanoid Robot Price Break 人形机器人价格突破
  • nats 消息系统架构
  • 【个人开发】cuda12.6安装vllm安装实践【内含踩坑经验】
  • 【自学笔记】人工智能基础知识点总览-持续更新
  • xpath语法以及基本使用
  • npm安装时无法访问github域名的解决方法
  • 视觉定位VPS的现状与未来
  • 华纳云:如何从服务器日志中发现僵尸进程?
  • unity 实时光为什么无法切换为烘焙光