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

浅拷贝和深拷贝

一、定义

  1. 浅拷贝(Shallow Copy)

    • 拷贝的是对象的第一层属性值:

      • 如果属性是基本类型,直接拷贝值;

      • 如果属性是引用类型(如对象、数组、函数),拷贝的是引用地址,并不会复制内容。

    • 结果:原始对象和新对象共享引用类型属性。

  2. 深拷贝(Deep Copy)

    • 递归地拷贝对象的所有层级属性:

      • 不论是基本类型还是引用类型,

      • 最终生成的对象是完全独立的副本,与原对象没有任何共享。

    • 结果:原始对象和新对象完全独立,互不影响。

二、实现方式

1. 浅拷贝实现方式

方法一:Object.assign()

const obj = { a: 1, b: { c: 2 } };
const shallowCopy = Object.assign({}, obj);

方法二:展开运算符(spread syntax)

const shallowCopy = { ...obj };

方法三:数组用 slice() 或 concat()

const arr = [1, 2, 3];
const newArr = arr.slice(); // 或 arr.concat();

注意:这些方法只复制一层,嵌套对象仍然是引用。

2. 深拷贝实现方式

方法一:JSON.parse(JSON.stringify(obj))【简单、常见】

const deepCopy = JSON.parse(JSON.stringify(obj));
  • 优点:简单直接。

  • 缺点:

    • 会忽略 undefined、function、symbol。

    • 无法处理 Date、RegExp、Map、Set 等特殊类型。

    • 会丢失原型链。

方法二:递归实现

function deepClone(obj, map = new WeakMap()) {// 原始类型直接返回(包括 BigInt、Symbol、null、undefined、string 等)if (obj === null || typeof obj !== 'object') return obj;// 循环引用处理if (map.has(obj)) return map.get(obj);// 特殊类型处理if (obj instanceof Date) return new Date(obj.getTime());if (obj instanceof RegExp) return new RegExp(obj.source, obj.flags);if (obj instanceof Error) {const copy = new obj.constructor(obj.message);copy.stack = obj.stack;return copy;}// 函数不拷贝,直接返回原始引用(你也可以选择抛错或深克隆 Function)if (typeof obj === 'function') return obj;// 保留原型const result = Array.isArray(obj)? []: Object.create(Object.getPrototypeOf(obj));// 保存到 WeakMap,处理循环引用map.set(obj, result);// 拷贝所有属性(包括 Symbol 和不可枚举)Reflect.ownKeys(obj).forEach((key) => {const desc = Object.getOwnPropertyDescriptor(obj, key);if (desc && 'value' in desc) {desc.value = deepClone(obj[key], map);}Object.defineProperty(result, key, desc);});return result;
}

方法三:使用 Lodash 的 cloneDeep

npm install lodash
import cloneDeep from 'lodash/cloneDeep';const deepCopy = cloneDeep(obj);
  • 最稳定,支持各种边界情况。

三、实际应用场景

浅拷贝使用场景

  • 只操作对象的第一层结构时:
const state = { count: 1 };
const newState = { ...state, count: 2 };
  • React/Vue中设置状态或props更新时,常用于不可变数据操作。

深拷贝使用场景

  • 需要完全隔离副本,防止引用污染:

    • Redux 状态管理中做 immutable 数据更新;

    • 配置数据模板复制;

    • 表单的“还原为初始值”操作;

    • 克隆嵌套数据结构(如嵌套对象或数组);

四、图示理解

const original = {name: "小明",info: { age: 26 }
};const shallow = { ...original };
shallow.info.age = 30;console.log(original.info.age); // 💥 30(引用被共享)const deep = JSON.parse(JSON.stringify(original));
deep.info.age = 40;console.log(original.info.age); // ✅ 30(深拷贝后独立)

五、总结对比表格

特性浅拷贝深拷贝
是否递归
引用类型共享是(只拷贝引用)否(完全复制)
实现难度简单相对复杂
性能慢(尤其大数据结构)
适用场景扁平数据结构嵌套结构、需要独立副本时
http://www.dtcms.com/a/306508.html

相关文章:

  • uni-app,uni.navigateTo
  • 【LangChain4j 详解】Java生态大语言模型框架设计哲学与架构原理
  • Node.js以及异步编程
  • vue模块化导入
  • 网络安全学习第16集(cdn知识点)
  • Android调用python库和方法的实现
  • 开源项目:排序算法的多种实现方式
  • DAY15-指针(3)
  • 解决:React Native 中常见的 状态栏遮挡内容
  • python 中 TypeError: self类型对象传入错误解决办法
  • 在职申硕,怎么选适合自己的学科专业呢?
  • 计算机网络1-3:三种交换方式
  • sed编程入门
  • Android RTMP推送|轻量级RTSP服务同屏实践:屏幕+音频+录像全链路落地方案
  • 本地 docker 部署 HAR包分析工具 harviewer
  • 2025年7月技术问答第5期
  • MySQL: with as与with RECURSIVE如何混合使用?
  • 【算法】十大排序算法超深度解析,从数学原理到汇编级优化,涵盖 15个核心维度
  • 专题:2025机器人产业技术图谱与商业化指南|附130+份报告PDF、数据汇总下载
  • C++实战:抖音级视频应用开发精髓
  • LazyLLM教程 | 第2讲:10分钟上手一个最小可用RAG系统
  • [极客时间]LangChain 实战课 -----|(11) 记忆:通过Memory记住客户上次买花时的对话细节
  • macOS 设置 Claude Code
  • 02 NameServer是如何管理Broker集群的
  • 【STM32-HAL】 SPI通信与Flash数据写入实战
  • Elasticsearch(ES)基础语法(笔记)(持续更新)
  • MySQL索引和事务笔记
  • 如何通过项目管理系统提升交付率
  • Kafka 重复消费与 API 幂等消费解决方案
  • IO复用实现并发服务器