关于js深拷贝的深究

以下是一篇关于JavaScript深拷贝的详细文章结构,您可以直接使用或调整:

深入解析JavaScript深拷贝:原理、实现与避坑指南

一、为什么需要深拷贝?

在前端开发中,我们经常遇到对象/数组的复制需求。当直接使用=赋值时,实际上只是复制了引用地址(浅拷贝),导致修改新对象会影响原对象:

const obj = { a: 1, b: { c: 2 } };const shallowCopy = obj;shallowCopy.b.c = 3;console.log(obj.b.c); // 3 原对象被修改!

深拷贝能彻底解决这个问题,创建完全独立的新对象。—## 二、深拷贝常见方案对比### 1. JSON方法(有局限性)

const deepCopy = JSON.parse(JSON.stringify(obj));

缺点:- 无法处理undefinedfunctionSymbol- 忽略原型链- 循环引用会报错- 丢失特殊对象类型(如Date变为字符串)### 2. 第三方库(推荐)

// lodashimport { cloneDeep } from 'lodash';const deepCopy = cloneDeep(obj);

3. 手动实现(本文重点)—## 三、手写深拷贝函数(进阶版)### 基础版本

function deepClone(target) {  if (typeof target !== 'object' || target === null) {    return target; // 基本类型直接返回  }    const cloneTarget = Array.isArray(target) ? [] : {};    for (let key in target) {    if (target.hasOwnProperty(key)) {      cloneTarget[key] = deepClone(target[key]);    }  }    return cloneTarget;}

进阶优化逐步解决以下问题:1. 循环引用问题

function deepClone(target, map = new WeakMap()) {  if (map.has(target)) return map.get(target);  // ...其他逻辑  map.set(target, cloneTarget);  // ...递归拷贝}```2. **特殊对象处理**```javascript// 获取对象的构造函数const constructor = target.constructor;// 处理Dateif (target instanceof Date) {  return new Date(target);}// 处理RegExpif (target instanceof RegExp) {  return new RegExp(target);}// 处理Map/Setif (target instanceof Map) {  const cloneMap = new Map();  target.forEach((value, key) => {    cloneMap.set(key, deepClone(value));  });  return cloneMap;}// Set同理
  1. 函数拷贝(视需求决定是否保留引用)
    javascript if (typeof target === 'function') { return target.bind({}); // 简单处理}

四、现代API方案

1. structuredClone

支持:Array/Object/Date/RegExp/Map/Set等 限制:不支持函数、DOM节点、原型链### 2. MessageChannel

function structuralClone(obj) {  return new Promise(resolve => {    const { port1, port2 } = new MessageChannel();    port2.onmessage = ev => resolve(ev.data);    port1.postMessage(obj);  });}

五、总结

  • 深拷贝的核心是递归遍历+类型判断
  • 生产环境推荐使用成熟的工具库
  • 注意特殊对象类型和循环引用问题
  • 根据业务需求选择合适的拷贝方式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值