JavaScript中的深拷贝与浅拷贝

embedded/2024/9/23 18:03:11/

目录

引言:

一、浅拷贝(Shallow Copy)

二、深拷贝(Deep Copy)

实现深拷贝的方法:

     1.使用JSON.parse(JSON.stringify(obj))

     2.使用递归实现深拷贝

三、总结

引言

        在JavaScript中,当我们需要复制一个对象时,可能会遇到深拷贝和浅拷贝的问题。这两种拷贝方式在处理对象及其子对象时有着显著的区别。本文将详细介绍深拷贝和浅拷贝的概念、区别,以及实现深拷贝的几种方法。

一、浅拷贝(Shallow Copy)

        浅拷贝是创建一个新对象,并将原对象的属性值复制到新对象。但是,这里的“复制”是浅层次的。如果原对象的属性值是一个引用类型(如对象、数组等),那么复制的是这个引用类型的地址,而不是真正的对象。因此,新对象和原对象会共享这个引用类型的值。

代码示例

let obj1 = {    a: 1,  // a是一个基本类型(number)  b: { c: 2 }  // b是一个引用类型(对象),它的c属性也是一个基本类型(number)  
};  let obj2 = Object.assign({}, obj1); // 浅拷贝obj2.a = 3; // 修改obj2的a属性,由于a是基本类型,所以它在obj2中有了新的值,不影响obj1  
console.log(obj1.a); // 输出1,因为obj1的a属性没有被修改  obj2.b.c = 4; // 修改obj2的b对象的c属性,由于b是引用类型,obj2.b和obj1.b指向同一个对象,所以obj1的b对象的c属性也被修改了  
console.log(obj1.b.c); // 输出4,因为obj1和obj2的b属性指向同一个对象,所以修改是共享的

        当您在JavaScript中执行浅拷贝时,您实际上是在复制对象的顶层属性到新的对象。但是,如果这些属性是引用类型(如对象或数组),那么您复制的仅仅是这些引用类型的引用(即它们的内存地址),而不是实际的对象。

二、深拷贝(Deep Copy)

        深拷贝是创建一个新对象,并将原对象的属性值及其子对象的属性值都复制到新对象。深拷贝会递归地复制所有级别的属性,直到所有的属性都是基本类型为止。这样,新对象和原对象是完全独立的,互不影响。

实现深拷贝的方法

        1.使用JSON.parse(JSON.stringify(obj))

        这种方法简单方便,但有其局限性。它不能正确处理函数、循环引用、undefinedSymbol和某些Date对象等。

代码示例:

let obj1 = {  a: 1,  b: { c: 2 }  
};  let obj2 = JSON.parse(JSON.stringify(obj1)); // 深拷贝  obj2.a = 3; // 修改obj2的a属性,不影响obj1  
console.log(obj1.a); // 输出1  obj2.b.c = 4; // 修改obj2的b对象的c属性,不影响obj1  
console.log(obj1.b.c); // 输出2
        2.使用递归实现深拷贝

        递归方法可以实现更精确的深拷贝,可以处理函数、循环引用等复杂情况。但需要注意递归终止条件和循环引用的处理。

代码示例:

function deepCopy(obj, hash = new WeakMap()) {  if (typeof obj !== 'object' || obj === null) {  return obj;  }  if (hash.has(obj)) {  return hash.get(obj);  }  let copy = Array.isArray(obj) ? [] : {};  hash.set(obj, copy);  for (let key in obj) {  if (obj.hasOwnProperty(key)) {  copy[key] = deepCopy(obj[key], hash);  }  }  return copy;  
}  // 使用示例  
let obj1 = {  a: 1,  b: { c: 2 }  
};  let obj2 = deepCopy(obj1); // 深拷贝  // 修改操作...

三、总结

        深拷贝和浅拷贝在处理JavaScript对象时有着显著的区别。浅拷贝只复制对象的顶层属性,如果属性值是引用类型,则复制的是引用地址;而深拷贝会递归地复制对象的所有属性,包括子对象,使得新对象和原对象是完全独立的。在实际开发中,需要根据具体的需求来选择使用哪种拷贝方式,并注意各种拷贝方法的限制和优缺点。


http://www.ppmy.cn/embedded/33881.html

相关文章

5.5代码

目录 1.内存空间 1.内存空间 真的要吐了,人都麻了题还没看完,看样子就是要想办法提取出来想要的东西2022第十三届蓝桥杯决赛C/C大学A组-C题内存空间_蓝桥杯a组c语言题目-CSDN博客 这个是一个非常清晰的代码,好几个帖子都管这个题叫大模拟题…

【华为】路由综合实验(OSPF+BGP基础)

【华为】路由综合实验 实验需求拓扑配置AR1AR2AR3AR4AR5PC1PC2 查看通信OSPF邻居OSPF路由表 BGPBGP邻居BGP 路由表 配置文档 实验需求 ① 自行规划IP地址 ② 在区域1里面 启用OSPF ③ 在区域1和区域2 启用BGP,使AR4和AR3成为eBGP,AR4和AR5成为iBGP对等体…

远程为ubuntu安装teamviwer(无UI界面) - 简书

远程为ubuntu安装teamviwer(无UI界面) - 简书 远程为ubuntu安装teamviwer(无UI界面) - 简书

Linux使用单总线驱动DS18b20

onewire单总线: 一. 基础知识: 单总线:串行模式,一条线,包括时钟线和数据线,根据设备地址,像IIC一样可实现一主多从。 常见引脚:三根线,信号线,vcc&#xf…

八股文(C#篇)

C#中的数值类型 堆和栈 值类型的数据被保存在栈(stack)上,而引用类型的数据被保存在堆(heap)上,当值类型作为参数传递给函数时,会将其复制到新的内存空间中,因此在函数中对该值类型的修改不会影…

【机器学习笔记】第一章绪论

一,一些概念 1.损失函数;反映预测结果和实际结果的差异 2.泛化能力:模型适用于新样本的能力 3.过拟合:模型在训练集上表现很好,但是泛化能力 二,机器学习全流程 其中数据预处理 深度学习:人工神经网络为…

力扣每日一题109:有序链表转换二叉搜索树

题目 中等 给定一个单链表的头节点 head ,其中的元素 按升序排序 ,将其转换为 平衡 二叉搜索树。 示例 1: 输入: head [-10,-3,0,5,9] 输出: [0,-3,9,-10,null,5] 解释: 一个可能的答案是[0,-3,9,-10,null,5],它…

讯饶科技 X2Modbus 敏感信息泄露

讯饶科技 X2Modbus 敏感信息泄露 文章目录 讯饶科技 X2Modbus 敏感信息泄露漏洞描述影响版本实现原理漏洞复现修复建议 漏洞描述 X2Modbus是一款功能很强大的协议转换网关, 这里的X代表各家不同 的通信协议,2是To的谐音表示转换,Modbus就是最…