You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 09:44:06