救命!改了 A 怎么 B 也变了?JSON 深拷贝救我狗命

直接上处理方式:采用 JSON.parse(JSON.stringify(value))

       

目录

一、先搞懂:为什么直接赋值会出问题?

二、最简单的深拷贝方案:JSON 序列化反序列化

1. 核心原理

2. 实战用法:解决「改 A 变 B」的问题

❌ 错误写法(引用赋值)

✅ 正确写法(深拷贝赋值)

注意事项


         一不小心就又在项目里踩了「对象赋值后牵一发而动全身」的坑:明明只是想修改 新对象,结果原对象也跟着变了,导致数据错乱。翻了翻代码才发现,问题出在最基础的赋值操作上 ——

 this.modelCategory = tempItem?.modelCategorys?.value。

一、先搞懂:为什么直接赋值会出问题?

        在 JavaScript 里,数据类型分为「基本类型」(string、number、boolean 等)和「引用类型」(object、array、function 等)。这两类数据的赋值逻辑完全不同:

  • 基本类型赋值:例如let aa=1,let b=aa,会直接复制一份值给 b。此时 aa 和 b 是独立的,改 aa 不会影响 b。
  • 引用类型赋值:比如let aa={name:'数额'};let b=aa,并不会复制对象本身,而是把对象在内存中的「地址」赋值给了 b。也就是说,aa 和 b 指向的是同一个对象,改其中一个,另一个自然会跟着变。

        这就是开头我遇到的问题:this.modelCategory 和 tempItem?.modelCategorys?.value指向了同一个对象,所以修改前者时后者也被篡改了。要解决这个问题,就需要创建一个「完全独立的新对象」,也就是常说的「深拷贝」。

二、最简单的深拷贝方案:JSON 序列化反序列化

        对于大部分日常场景,JSON.parse(JSON.stringify(obj))是实现深拷贝最便捷的方法,没有之一。

1. 核心原理

这行代码其实做了两件事:

  1. JSON.stringify(obj):把 JavaScript 对象转换成 JSON 字符串(序列化),这个过程会脱离原对象的内存引用。
  2. JSON.parse(...):把 JSON 字符串重新转换成 JavaScript 对象(反序列化),这个过程会在内存中创建一个全新的对象。

一拆一装之间,新对象和原对象就彻底「断了联系」,实现了真正的独立。

2. 实战用法:解决「改 A 变 B」的问题

回到我开头的项目场景,只需要把简单赋值改成带 JSON 转换的赋值,问题就迎刃而解。

❌ 错误写法(引用赋值)
handleOntemplate(template){
 this.modelCate=template?.modelCate?.value
}

         在这段代码中,使用最开始简单赋值。在我实战代码中,第一次输入数据——点击【重置】——点击【查询】——再次输入数据——点击【重置】,但此时数据没有恢复初始值,打印template.modelCate.vaule,发现值也跟着刚才变了。

✅ 正确写法(深拷贝赋值)
handleOntemplate(template){
 //this.modelCate=template?.modelCate?.value
 //改为
this.modelCate=template?.modelCate?.value?JSON.parse(JSON.stringify(template?.modelCate?.value)):[]
}

这段代码中,this.modelCate 是一个独立的新对象,后续修改不会影响其他变量。       

注意事项

  • 它无法拷贝函数、正则表达式、日期对象等特殊类型,序列化这些类型时会丢失信息或出现异常。
  • 不能处理循环引用的对象,否则会报错。
  • 对于包含大量嵌套层级的复杂对象,序列化和反序列化过程可能会有一定性能消耗,但在大多数业务场景下,性能影响是可以接受的。

      

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值