AngularJS 1.6对象克隆与引用赋值问题咨询
为什么直接赋值AngularJS ng-repeat的item会出问题?
这问题其实是JavaScript对象引用机制的经典坑,我来给你拆解清楚:
1. 直接赋值this.updateData = item的问题根源
在JavaScript里,对象是引用类型——当你把item直接赋值给this.updateData时,你并没有复制这个对象本身,只是让updateData和item指向了内存中同一个对象实例。
结合你的代码场景来看:
- 当你在
updateDataFun里执行this.updateData = item后,this.updateData和aList数组里的那个item其实是同一个东西。 - 如果你之后修改
this.updateData的属性(比如在编辑表单里修改它的字段),aList里对应的原始item会同步被修改——因为它们共享同一个内存引用。 - 就算你调用
cancelUpdate()把this.updateData设为空对象,这只是让updateData指向了一个新的空对象,但之前修改过的原始item已经被改变了,没法恢复,这就是你遇到的异常问题。
2. 为什么Object.assign({}, item)能解决问题
Object.assign({}, item)做的是浅拷贝操作:
- 它会创建一个全新的空对象
{},然后把item的所有可枚举属性一一复制到这个新对象里。 - 这样
this.updateData就指向了一个独立的新对象,和原来的item彻底断开了引用关系。 - 之后你修改
updateData的任何属性,都不会影响aList里的原始数据;调用cancelUpdate()清空后,原始的item也不会被污染,完美解决了你的问题。
补充说明
需要注意的是,Object.assign是浅拷贝——如果item里包含嵌套的对象(比如item.address = {city: "Beijing"}),那嵌套的对象部分还是会保持引用关系。如果你的业务里有嵌套对象的场景,可能需要用深拷贝(比如递归拷贝、或者JSON.parse(JSON.stringify(item)),但后者有局限性),不过如果你的item是扁平的简单对象,Object.assign完全够用。
内容的提问来源于stack exchange,提问作者Saiful Azad
相关产品推荐
相关产品推荐

