Vue中对象属性意外变更问题:如何避免源数组随副本修改?
解决Vue中修改拷贝对象导致原对象被改变的问题
这个坑我之前踩过!你遇到的问题核心是JavaScript的引用类型特性:当你执行var thisHotels = this.hotelRoomArr时,并没有创建一个新的对象副本,只是把this.hotelRoomArr的内存引用赋值给了thisHotels——说白了,这两个变量指向的是同一个对象。所以你修改thisHotels的任何属性,本质上都是在修改原对象this.hotelRoomArr。
要避免这种情况,你需要创建原对象的深拷贝(因为你的数据是嵌套结构,浅拷贝不够用),下面给你几种可行的方案:
方案1:JSON序列化反序列化(简单场景首选)
如果你的对象里没有函数、Symbol、undefined这类无法被JSON序列化的内容,这个方法最快捷:
filterHotels:function(){ // 深拷贝原数组,生成完全独立的新对象 var thisHotels = JSON.parse(JSON.stringify(this.hotelRoomArr)); console.log(thisHotels['107572']['rooms']); thisHotels['107572']['rooms'] = {}; console.log(this.hotelRoomArr['107572']['rooms']); // 现在原对象不会被修改了! }
注意:这个方法会丢失无法序列化的属性,如果你的数据里包含特殊类型,不要用这个。
方案2:自定义递归深拷贝(复杂场景适用)
如果需要保留函数、特殊对象(比如Date),可以自己写一个递归深拷贝函数:
// 先定义深拷贝工具函数 function deepClone(obj) { // 非对象类型直接返回 if (obj === null || typeof obj !== 'object') return obj; // 处理Date对象 if (obj instanceof Date) return new Date(obj); // 处理数组 if (obj instanceof Array) return obj.map(item => deepClone(item)); // 处理普通对象 const clonedObj = {}; for (let key in obj) { if (obj.hasOwnProperty(key)) { clonedObj[key] = deepClone(obj[key]); } } return clonedObj; } // 在组件方法里使用 filterHotels:function(){ var thisHotels = deepClone(this.hotelRoomArr); thisHotels['107572']['rooms'] = {}; console.log(this.hotelRoomArr['107572']['rooms']); // 原对象不受影响 }
方案3:使用Lodash的cloneDeep(依赖第三方库)
如果你项目里已经引入了Lodash,可以直接用它的深拷贝方法,省心又可靠:
// 先确保安装了lodash:npm install lodash import _ from 'lodash'; filterHotels:function(){ var thisHotels = _.cloneDeep(this.hotelRoomArr); thisHotels['107572']['rooms'] = {}; }
总结一下:关键是要让thisHotels成为一个完全独立于原对象的新副本,而不是原对象的引用,这样修改副本就不会影响原数据了。
内容的提问来源于stack exchange,提问作者Mak_091
相关产品推荐
相关产品推荐

