uni-app 局部变量进行数组push, unshift等操作导致多个数组发生相同变化

uni-app 局部变量进行数组push, unshift等操作导致多个数组发生相同变化

信息类别 详情
产品分类 uniapp/App
PC开发环境 Mac
PC版本号 11.5.1
HBuilderX 正式
HBuilderX版本号 3.1.22
手机系统 全部
手机厂商 苹果
页面类型 vue
打包方式 云端
项目创建方式 HBuilderX

测试过的手机:

  • 苹果8p
  • 小米11pro
  • 谷歌浏览器

示例代码:

let aa = [];
let ab = [];
//评论回复体
aa = that.detail.circleComment.comments;
//该值为前端回复评论所需要的对象体,包含content,id,等字段
let ac ={};
ac = that.commitForm;
//插入
aa.unshift(ac);
//回填
that.detail.circleComment.comments = aa;  

依次输入 {content:1}{content:2}{content:3}{content:4} 结果始终依次为 1 2,2 3,3,3 4,4,4,4

根据网络中别人给的解释:说明多次操作 指向的始终是同一个内存地址;

操作步骤:

let aa = [];
let ab = [];
aa = that.detail.circleComment.comments;
let ac ={};
ac = that.commitForm;
aa.unshift(ac);
that.detail.circleComment.comments = aa;

预期结果:

输入 1 ,2 ,3,4 结果应该为 1,2,3,4

实际结果:

输入 1 ,2 ,3,4 结果始终依次为 1 2,2 3,3,3 4,4,4,4

bug描述:

使用 pushunshift 进行数组填充时候,每次都会覆盖上一次的数据,与 https://blog.csdn.net/xiaoye319/article/details/78416762?utm_source=blogxgwz2 类似, 实际开发过程中,不管如何使用 let var 等变量进行定义,新建都始终指向一个地址,导致每次添加,都会添加的数值始终一样。


更多关于uni-app 局部变量进行数组push, unshift等操作导致多个数组发生相同变化的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

经过多次实践后,发现 ac = that.commitForm;
会将data中的commitForm 内存复制到变量中,应该改成单个赋值。 ac.某变量 = that.commitForm

更多关于uni-app 局部变量进行数组push, unshift等操作导致多个数组发生相同变化的实战教程也可以访问 https://www.itying.com/category-93-b0.html


这是一个典型的JavaScript引用类型赋值问题,不是uni-app的bug。

在你的代码中:

aa = that.detail.circleComment.comments;

这里aa并没有创建一个新的数组,而是获得了对that.detail.circleComment.comments数组的引用。当你执行aa.unshift(ac)时,实际上是在修改原始数组。

更关键的问题是ac对象:

let ac = {};
ac = that.commitForm;

ac同样只是引用了that.commitForm对象。如果that.commitForm在后续操作中没有被重新创建(比如只是修改了其属性),那么每次unshift操作添加的都是同一个对象引用。

解决方案:

  1. 深拷贝数组
let aa = [...that.detail.circleComment.comments]; // 或 JSON.parse(JSON.stringify())
  1. 创建新对象
let ac = {...that.commitForm}; // 浅拷贝对象属性
// 或者深拷贝
let ac = JSON.parse(JSON.stringify(that.commitForm));
  1. 完整修正代码
// 创建数组的副本
let aa = [...that.detail.circleComment.comments];
// 创建对象的副本
let ac = {...that.commitForm};
// 插入
aa.unshift(ac);
// 回填
that.detail.circleComment.comments = aa;
回到顶部