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

JS中使用Set为对象数组去重出现结果差异的原理咨询

原理说明
  • JavaScript 中的 Set 去重使用的是 SameValueZero 相等判定规则,和 === 运算的逻辑基本一致,仅对 NaN 的判定有差异(Set 会认为两个 NaN 是相等的)。
  • 你遇到的差异本质是引用类型和值类型的判定规则不同:对象属于引用类型,相等判断比较的是内存引用地址,而非对象内部的属性值。

两个案例的差异解释

  1. 第一个数组 arr 中的三个对象是独立声明的对象字面量,每一个都会在堆内存中开辟独立的存储空间,对应的引用地址完全不同。就算三个对象的属性名、属性值完全一致,在 Set 判定时也会被识别为三个不同的值,因此最终 Set 长度为 3,没有去重效果。
  2. 第二个数组 sameArr 中的三个元素都是同一个 obj 对象的引用,指向同一块内存地址,Set 判定时会认为是同一个值,因此去重后长度为 1。

常见对象数组去重方案

如果你需要根据对象内容去重,可以根据场景选择以下方案:

按指定属性组合去重

适合明确知道要以哪几个属性作为去重判定依据的场景,性能更稳定:

// 以 type 和 power 组合作为去重依据
const uniqueMap = new Map()
arr.forEach(item => {
  const key = `${item.type}-${item.power}`
  if (!uniqueMap.has(key)) {
    uniqueMap.set(key, item)
  }
})
const uniqueArr = Array.from(uniqueMap.values())

全属性序列化去重

适合结构简单、属性顺序一致的普通对象,注意该方案会丢失属性值为 undefined、Function、Symbol 的内容,循环引用的对象也会报错:

const uniqueArr = Array.from(new Set(arr.map(item => JSON.stringify(item))))
  .map(str => JSON.parse(str))

内容的提问来源于stack exchange,提问作者PCPbiscuit

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 03:15:02