JS 浅拷贝和深拷贝详解(巨详细)

article/2025/10/5 14:16:35

目录

一、前置知识详解

1.1.JavaScript数据类型

1.2.理解传值和传址

二、浅拷贝

2.1.浅拷贝的定义和原理

2.2.实现浅拷贝的方法

2.2.1.手写递归实现

2.2.2.利用展开语法实现浅拷贝

 2.2.3.Object.assign进行对象的合并

2.2.4.利用Array.prototype.,slice()

2.2.5.利用Array.prototype.contact()

三、深拷贝

3.1.深拷贝的定义及原理

3.2.深拷贝的实现方法

3.2.1.递归实现深拷贝

3.2.2.JSON.parse(JSON.stringify(待拷贝对象)

 3.2.3.jQuery 中的 $.extend() 第一个参数设置为true为深拷贝,为false为浅拷贝(要引入JQuery库)

3.2.4.引入loadsh,提供 cloneDeep 实现


一、前置知识详解

在学习浅拷贝和深拷贝之前,我们有必要了解的前置知识

1.1.JavaScript数据类型

JavaScript的数据类型分为基本类型:Number,String,Boolean,Undefined,Null,Symbol,BigInt

                                          引用l类型:对象(Object),数组(Array),函数(Function)

基本类型数据保存在在栈内存中

引用类型数据保存在堆内存中,引用数据类型的变量是一个指向堆内存中实际对象的引用,存在栈中

1.2.理解传值和传址

传值:开辟新内存区域存储值

代码示例如下

            let a = 3;let b = a;console.log(a, b);  // 3 3b = 5;  console.log(a, b);  // 3 5

传址:传递内存地址,而不开辟新空间

            let obj = {name: 'zs',age: 20,};let obj1 = obj;console.log(obj, obj1);obj1.name = 'lisi';console.log(obj, obj1);

 

输出内容相同,obj和obj1指向了同一个内存地址。

二、浅拷贝

2.1.浅拷贝的定义和原理

浅拷贝,指的是创建新的数据,这个数据有着原始数据属性值的一份精确拷贝

如果属性是基本类型,拷贝的就是基本类型的值。如果属性是引用类型,拷贝的就是内存地址

即浅拷贝是拷贝一层,深层次的引用类型则共享内存地址

2.2.实现浅拷贝的方法

2.2.1.手写递归实现

            // 手写实现浅拷贝function shallowClone(obj) {let newObj = {};for (let i in obj) {// 只要是obj的属性,直接复制一份给newObjif (obj.hasOwnProperty(i)) {newObj[i] = obj[i];}}return newObj;}const person = {name: 'zs',hobby: ['排球', '网球', '篮球'],};const person1 = shallowClone(person);console.log(person);console.log(person1);person1.name = 'lisi';person1.hobby[0] = '足球';console.log(person);console.log(person1);

打印输出结果如下

2.2.2.利用展开语法实现浅拷贝

            let obj = {name: 'zs',lessons: ['hobby', 'suxexu', 'kligh'],};let hd1 = { ...obj };hd1.name = 'lisi';hd1.lessons[0] = 'math';console.log(obj);console.log(hd1);

 2.2.3.Object.assign进行对象的合并

            let obj = {name: 'zs',lessons: ['hobby', 'suxexu', 'kligh'],};let newObj = Object.assign({}, obj);newObj.lessons[0] = 'math';console.log(obj);console.log(newObj);

2.2.4.利用Array.prototype.,slice()

            const arr = [1, 2, { name: 'nordon' }];const newArr = arr.slice();newArr[2].name = 'wy';console.log(arr);console.log(newArr);

2.2.5.利用Array.prototype.contact()

            const arr = [1, 2, { name: 'nordon' }];const newArr = arr.concat();newArr[2].name = 'wy';console.log(arr);console.log(newArr); 

三、深拷贝

3.1.深拷贝的定义及原理

  深拷贝开辟一个新的栈,两个对象属性完成相同,但是对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性

3.2.深拷贝的实现方法

3.2.1.递归实现深拷贝

第一种方法

            function deepClone(obj) {let newObj = obj instanceof Array ? [] : {};for (let i in obj) {if (obj.hasOwnProperty(i)) {if (obj[i] && typeof obj[i] == 'object') {// 若对象属性还是引用类型,进行递归newObj[i] = deepClone(obj[i]);} else {// 对象属性为基础数据类型,直接赋值newObj[i] = obj[i];}}}return newObj;}const obj = {name: 'zs',hobby: ['排球', '网球', '乒乓球'],};const newObj = deepClone(obj);newObj.name = 'lisi';newObj.hobby[0] = '篮球';console.log(obj);console.log(newObj);

第二种方法,巧妙运用Object.entries(obj)遍历对象的属性和值

            function deepClone(obj) {let newObj = obj instanceof Array ? [] : {};for (const [k, v] of Object.entries(obj)) {newObj[k] = typeof v == 'object' ? deepClone(v) : v;}return newObj;}const obj = {name: 'zs',hobby: ['排球', '网球', '乒乓球'],};const newObj = deepClone(obj);newObj.name = 'lisi';newObj.hobby[0] = '篮球';console.log(obj);console.log(newObj);

输出结果相同,如下:

3.2.2.JSON.parse(JSON.stringify(待拷贝对象)

            const obj = {name: 'zs',hobby: ['排球', '网球', '乒乓球'],};const newObj = JSON.parse(JSON.stringify(obj));newObj.name = 'lisi';newObj.hobby[0] = '篮球';console.log(obj);console.log(newObj);

 3.2.3.jQuery 中的 $.extend() 第一个参数设置为true为深拷贝,为false为浅拷贝(要引入JQuery库)

            const obj1 = {a: 1,b: { f: { g: 1 } },c: [1, 2, 3],};const obj2 = $.extend(true, {}, obj1);console.log(obj1.b.f === obj2.b.f);

3.2.4.引入loadsh,提供 cloneDeep 实现

vue中使用loash库实现深拷贝的步骤

  1. 安装loadsh    npm i --save lodash
  2. 引入loadsh    import _ from 'lodash'
  3. 直接调用loadsh库的方法 const newObj = _.cloneDeep(this.obj)


http://chatgpt.dhexx.cn/article/jQk2wf51.shtml

相关文章

SV中的浅拷贝和深拷贝

1.浅拷贝 浅拷贝: 只拷贝对象中的数据变量,而对于对象中的数据操作(一般为任务和函数)和其中定义的其他类的句柄,采用类似“引用”的方式,浅拷贝前后共用同一内存空间。 可以使用new操作符进行复制。如果一个类包含指向另一个类的…

什么是浅拷贝和深拷贝?

文章目录 1、什么是浅拷贝?2、什么是深拷贝?2.1、常见的深拷贝方式 在Java语言中,当我们需要拷贝一个Java对象的时候,常见的会有两种方式的拷贝:浅拷贝与深拷贝。 浅拷贝:只是拷贝了源对象的地址,所以源对象…

基于java实现浅拷贝和深拷贝

目录 1、概念2、浅拷贝2.1、浅拷贝实战 3、深拷贝3.1、嵌套 clone 方法3.2、使用序列化流3.3、使用开源工具类 1、概念 浅拷贝:在拷贝一个对象时,复制基本数据类型的成员变量,但对引用数据类型的成员变量只进行引用的传递(复制其…

js实现浅拷贝和深拷贝

一.数据类型 数据分为基本数据类型和引用数据类型 基本数据类型(String, Number, Boolean, Null, Undefined,Symbol) 引用数据类型(Object[Array属于Object]) 基本数据类型的特点:直接存储在栈(stack)中的数据 引用数据类型的特点…

浅拷贝和深拷贝

最近学习string类的时候感觉这里概念有点混淆,浅拷贝与深拷贝的区别,上网查了一下,原来没我想 的难么复杂,以下是我的理解,如果有不对的地方求大佬留言交流交流。 浅拷贝: 顾名思义就是浅层的拷贝&#xff…

理解浅拷贝和深拷贝以及实现方法

一、数据类型 数据分为基本数据类型(String, Number, Boolean, Null, Undefined,Symbol)和引用数据类型Object,包含(function,Array,Date)。 1、基本数据类型的特点:直接存储在栈内存中的数据 …

VUE浅拷贝和深拷贝

文章目录 前言一、数据类型1.1.基本数据类型1.2.引用数据类型1.3.区别 二、浅拷贝2.1.定义2.2.浅拷贝特点 三、深拷贝3.1.定义3.2.深拷贝特点 四、拷贝实现方案4.1.Object.assign()4.2.concat()4.3.slice()4.4.JSON.parse(JSON.stringify())4.5.cloneDeep() 五、结论 前言 在理…

C# 中的浅拷贝和深拷贝

在本文中,将通过示例讨论C#中的浅拷贝和深拷贝。这是上一篇文章的续篇。因此,在继续本文之前,请阅读以前的文章,其中之前使用示例讨论了C#中的原型设计模式。 什么是深拷贝和浅拷贝? 浅复制和…

JAVA 浅拷贝和深拷贝

拷贝 拷贝即对已有的数据创建一个副本,在 Java 中,拷贝可分为引用拷贝、浅拷贝、深拷贝。 引用拷贝 在 Java 中,实例化后的对象存储在堆区,而局部变量存放在局部变量表(栈)中,如: public void yinYongC…

js浅拷贝和深拷贝

1、JS数据类型 基本数据类型:Boolean、String、Number、null、undefined 引用数据类型:Object、Array、Function、RegExp、Date等 2、深拷贝与浅拷贝 深拷贝和浅拷贝都只针对引用数据类型, 浅拷贝会对对象逐个成员依次拷贝,但…

C++浅拷贝和深拷贝

1、浅拷贝 浅拷贝:又称值拷贝,将源对象的值拷贝到目标对象中去,本质上来说源对象和目标对象共用一份实体,只是所引用的变量名不同,地址其实还是相同的。 举个简单的例子,你的小名叫西西,大名叫…

彻底理解Python中浅拷贝和深拷贝的区别

目录 前言 1. 浅拷贝和深拷贝的概念 2. is和的区别 3. 赋值操作 4. copy模块里面的copy()方法 5. copy模块里面的deepcopy()方法 6.字典自带的copy方法 7.切片表达式拷贝 8.总结 前言 Python 的所有变量其实都是指向内存中的对象的一个指针,这确实和之前学…

如何理解java的回调函数?

对于技术问题,会用是一回事,理解这个技术问题的来龙去脉、设计者当初为什么要设计这个功能、这个技术问题有哪些优势、适用哪些场景又是另外回事了。 前者照猫画虎得其形,后者形神兼备得其意,这也是所谓青铜与王者的区别。 会使…

java使用回调函数

java回调函数 回调函数(callback Function),顾名思义就是用来回调的函数。在两个类A、B中,A在调用B接口的同时B也在调用A 回调函数也常用于线程中的异步获取消息。 举个简单的例子,公司中老板分发任务给员工A&#…

java中回调函数的实现

在java的事务中,有时候可能会遇到以下情况,第一步是更新某某表,中间可能要更新不确定的多步,最后一步是更新缓存,结构大致如下: (1)updateA(); (2)updateXX…

什么是java回调函数

回调函数 一:故事背景二:概念三:回调函数的作用四:java中如何进行回调4.1 类图4.2 定义回调接口4.3 实现回调接口4.4 调用方法使用回调函数4.5 Main函数调用4.6 总结描述 五:回调函数的优点5.1 灵活性5.2 解耦性5.3 异…

简单举例JAVA回调函数的实现

来自维基百科的对回调(Callback)的解释:In computer programming, a callback is any executable code that is passed as an argument to other code, which is expected to call back (execute) the argument at a given time. This execut…

java回调函数机制

Java回调函数机制 参考了网上的一些资料,下面也做出一些总结,供初学者了解学习。 一、 概述 软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用、回调、异步调用 。 同步调用:一…

java中如何实现回调函数

最近工作需要研究了一会别人写的库,其中充满着各种"回调函数",因此把自己理解给记录下来,存档。 首先我们来看看回调函数 这个概念的具体由来,百度百科的示义如下: 回调函数就是一个通过函数指针调用的函数。…

Java回调函数 + 使用案例

文章目录 前言什么是回调函数第0个版本第1个版本第2个版本第3个版本第4个版本第5个版本第6个版本回头解析前言描述的问题1. MethodIntrospector.selectMethods()2. 抽象类MethodIntrospector3. 方法selectMethods()4. 成员变量USER_DECLARED_METHODS5. 方法doWithMethods()6. d…