一、需求:点击编辑弹出编辑框,修改后的内容点击认按钮修改后的数据更新回显到原列表。今天优化代码的时候发现了Object.assign()和JSON.parse(JSON.stringify())的区别。
- 优化前代码如下:
// 编辑药品回显
editMedicData(data) {
this.tableData.adrDrugInfos.map((item) => {
if (item.orderId === data.orderId) {
item.suspectedConcomitant = data.suspectedConcomitant
item.genericName = data.genericName
item.shopName = data.shopName
item.approvalNumber = data.approvalNumber
item.manufacturer = data.manufacturer
item.batchNumber = data.batchNumber
item.startDate = data.startDate
item.endDate = data.endDate
item.dose = data.dose
item.doseUnit = data.doseUnit
item.frequency = data.frequency
item.routeName = data.routeName
item.formName = data.formName
item.reasonForUse = data.reasonForUse
item.remark = data.remark
}
return item
})
},
- 优化后代码如下:
// 编辑药品回显
editMedicData(data) {
this.tableData.adrDrugInfos.forEach((item) => {
if (item.orderId === data.orderId) {
item = Object.assign(item,data)
}
})
},
二、发现:在优化的时候发现使用JSON.parse(JSON.stringify())没有响应式赋值,虽然打印出来的数据是修改后的,但是页面还是显示之前的数据。只有使用Object.assign()才能响应式赋值起作用。
三、知识点:
Object.assign() 和 JSON.parse(JSON.stringify()) 都是用于对象的深拷贝(deep copy),但它们之间有一些重要的区别。
1.目标:
- Object.assign():用于将源对象的属性复制到目标对象。
- JSON.parse(JSON.stringify()):用于将一个对象序列化为字符串,再将字符串反序列化为一个新的对象。
2.处理能力:
- Object.assign():适用于只能拷贝可枚举的自身属性。它无法拷贝源对象的原型链上的属性和方法。
- JSON.parse(JSON.stringify()):能够拷贝源对象的自身属性和原型链上的属性和方法。它能够处理函数、正则表达式、Date 对象等特殊类型的属性。
3.引用处理:
- Object.assign():对于拷贝对象中的引用类型属性,它只是简单地将引用复制到目标对象中,这意味着源对象和目标对象可能会共享相同的引用。
- JSON.parse(JSON.stringify()):通过序列化和反序列化的过程,能够实现完全的深拷贝,即源对象和目标对象不共享引用。
4.错误处理:
- Object.assign():在拷贝过程中,如果源对象的属性是一个访问器属性(getter/setter),则会以其返回值作为值进行拷贝。但是,对于setter属性,它只会复制其值而不是复制setter本身。
- JSON.parse(JSON.stringify()):在序列化和反序列化的过程中,所有函数属性、undefined 属性和 symbol 属性都会被忽略。而对于包含循环引用的对象,或者无法被序列化的对象,这种方式会导致错误。
综上所述,如果你的对象只包含简单的属性,没有函数属性、循环引用等特殊情况,可以使用 Object.assign() 进行拷贝。如果你需要处理更复杂的对象,包括函数、正则表达式和循环引用等,建议使用 JSON.parse(JSON.stringify()) 进行深拷贝。