使用net Set()居然去重了包含数组的对象!(错误记录)

187 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情

使用net Set()居然去重了包含数组的对象!(错误)

事情是这样的,本来是为了赶时间使用new Set()对包含数组的对象进行去重,结果居然成功了。 当天夜里很晚了,没有深思,第二天想起来发现确实不太对劲。(深拷贝和浅拷贝的原因导致)

测试过程一

第一反应是vue3的特殊性,原因是写了一个html页面用js方法测试去重未果。

let arr = [{ name: '张三', value: 1 }, { name: '张三', value: 1 }, { name: '李四', value: 1 }, { name: '李四', value: 1 }, { name: '张三', value: 3 }, { name: '张三', value: 4 }];
let d = [...new Set(arr)]
console.log('去重成功了吗', d);

结果是没有成功。

参考网上的说法,使用将对象转成String的方式可以去重。

const d = [...new Set(arr.map(t => JSON.stringify(t)))].map(s => JSON.parse(s))

去重成功! 但是 我并没有在项目中使用这个方法。思考:为什么会成功?

测试过程二

在浏览器中使用debug,检测数据。以下是过程 经过debug,确实是成功去重了,但还是没懂。。。

1.png

2.jpg

3.jpg

4.jpg

QQ图片20221220193128.jpg

QQ图片20221220193134.jpg

测试过程三

去在各个交流群里问大佬,被大佬点醒, 于是关闭new Set(),使用for循环比较每个数据,

let array = [];
s.forEach(e => {
  array.push(...e.md)
});
this.$store.state.selectShopData.forEach(e => {
  if(e.pid){
    delete e.pid; 
  }
});
array.push(...this.$store.state.selectShopData)
for (let i = 0; i < array.length; i++) {
  if(array[i]==array[i+1]){
    console.log('相同的值',array[i]);
  }
}

结果无论是使用==还是===都相等。 为了验证,没有删除vuex中数据的额外属性pid,结果果然在array中也找到了这个数据。 所以其实是它们的引用地址一致,也就是它们的指向地址还是一样的。相同的数据,当然是相同的。(开始自闭)

这条数据的旅程

a组件的el-tree的节点(current-change事件)获取的节点数据 => b组件的el-tabletableData数据 => b组件el-tableselect事件获取的选中数据 => push入vuex中的selectShopData数组变量 => a组件的方法去重vuex中的selectShopData数组(成功)

期间这个数据的引用地址没有变化。所以期间一直是浅拷贝的数据在来回被使用!