关于JS的深拷贝与浅拷贝问题处理
1 let obj1 = { 2 a: 0, 3 b: 0 4 } 5 let obj2 = '' 6 7 // obj2 = obj1 8 // obj2.a = 10 9 // console.log(obj1, obj2); //{ a: 10, b: 0 } { a: 10, b: 0 }
可以看到,将obj1赋给obj2,我们改变的是obj2,而obj1也跟着改变了,这样肯定是不行的。
为什么会出现这种情况呢?其实,这是一个引用传递而不是值传递,obj1和obj2指向的是同一个内存地址。
如果我们不想让obj1的值跟着联动变化,应该怎么做呢?
这边我列举几种方法:
第一种:
可以先把obj1转换成字符串,然后在转换成对象,代码如下:
1 obj2 =JSON.parse(JSON.stringify(obj1)) 2 obj2.a = 10 3 console.log(obj1, obj2); //{ a: 0, b: 0 } { a: 10, b: 0 }
这种方法存在很大的问题。虽然他在 stackoverflow 是得票最多的一个答案,也是本人最喜欢的一个方法。
JSON.stringify() 将编码 JSON 支持的值。包含 Boolean,Number,String,以及对象,数组。其他任何内容都将被特殊处理。
undefined,Function,Symbol 时,它被忽略掉
Infinity,NaN 会被变成 null
Date 对象会被转化为 String (默认调用date.toISOString())
问:为什么JSON.stringify() 编码 JSON 支持的值那么少呢?
因为JSON是一个通用的文本格式,和语言无关。设想如果将函数定义也stringify的话,如何判断是哪种语言,并且通过合适的方式将其呈现出来将会变得特别复杂。特别是和语言相关的一些特性,比如JavaScript中的Symbol
第二种:
利用ES6扩展运算符(...)
对象中的扩展运算符(...)用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中
1 obj2 = {...obj1} 2 obj2.a = 10 3 console.log(obj1, obj2); //{ a: 0, b: 0 } { a: 10, b: 0 }
第三种:
Object.assign({},{},{}) 等价于第二种方法
Object.assign
方法用于对象的合并,将源对象(source)
的所有可枚举属性,复制到目标对象(target)
。
Object.assign
方法的第一个参数是目标对象,后面的参数都是源对象。(如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性)。
1 obj2 = Object.assign({}, obj1) 2 obj2.a = 10 3 console.log(obj1, obj2); //{ a: 0, b: 0 } { a: 10, b: 0 }
第四种:
引入Lodash内置的方法直接使用 --- 推荐
Lodash是一个著名的javascript原生库,不需要引入其他第三方依赖。是一个意在提高开发者效率,提高JS原生方法性能的JS库。简单的说就是,很多方法lodash已经帮你写好了,直接调用就行,不用自己费尽心思去写了,而且可以统一方法的一致性。Lodash使用了一个简单的 _ 符号,就像Jquery的 $ 一样,十分简洁。
1 import * as _ from 'lodash' 2 3 obj2 = _.cloneDeep(obj1) 4 obj2.a = 10 5 console.log(obj1, obj2); //{ a: 0, b: 0 } { a: 10, b: 0 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗