最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如何理解 Set 内部对 NaN 与正零和负零的唯一性判定规则
时间:2026-07-21 11:14:07 编辑:袖梨 来源:一聚教程网
Set 使用 SameValueZero 算法判断重复,将 +0、-0、0 视为相等,NaN 只保留一个,不依赖 === 也不完全等同 Object.is(),导致去重行为与直觉不符。
Set 用 SameValueZero 算法判断重复,不是 ===
Set 不是靠 === 判断两个值是否重复,而是用更底层的 SameValueZero 算法。这个算法和 Object.is() 几乎一样,但有个关键区别:它把 +0 和 -0 当作相等,而 Object.is(+0, -0) 返回 false。
NaN 在 Set 中只存一个,但 !== 自身
这是最常让人困惑的点:虽然 NaN === NaN 是 false,Object.is(NaN, NaN) 是 true,而 Set 选择的是“只留第一个 NaN”——它不依赖 ===,也不完全等同于 Object.is(),而是按规范硬编码了 NaN 的唯一性。
-
new Set([NaN, NaN, NaN])的.size是1 - 但
NaN === NaN始终为false,所以不能靠===模拟 Set 行为 - 如果你手动写去重逻辑(比如用
filter()+includes()),默认不会合并 NaN
+0 和 -0 在 Set 中无法共存
哪怕你显式写出 -0,Set 也会把它和 +0 当作同一个值:
new Set([+0, -0, 0]) // → Set { 0 }
注意:-0 被打印为 0,但它在内存中仍是 -0;只是 Set 内部判定时认为三者等价。
-
0、+0、-0插入任意顺序,最终只保留一个 -
Array.from(new Set([+0, -0]))[0] === -0可能为true(取决于插入顺序和引擎实现) - 不要依赖
JSON.stringify(-0)或String(-0)做唯一性预处理,它们都输出"0",会掩盖差异
实际去重时最容易忽略的边界
当你用 [...new Set(arr)] 去重数组,这些行为会悄悄影响结果:
-
["0", 0, false]→ 三个不同值(字符串、数字、布尔),不会被合并 -
[NaN, "NaN"]→ 两个不同值(类型不同),都会保留 -
[0, -0, Object.is(0, -0)]→false,但 Set 里仍只留一个 - 对象或函数传进去,永远按引用比较,
new Set([{a:1}, {a:1}])长度是2
真正需要稳定去重时,别直接塞原始数组进 Set——先统一转成字符串或提取 key,否则 +0/-0 和 NaN 的隐式合并可能破坏业务语义。
相关文章
- 苹果折叠屏爆料汇总:售价超两万,比例阔折叠 07-30
- 纪念碑谷3 纪念碑谷3手游玩法详解与体验评测 07-30
- 晴空双子金卡阵容推荐 晴空双子高性价比氪金养成指南 07-30
- 大周列国志全新派系系统 07-30
- 兔小萌世界甜系小房间搭建指南 兔小萌世界高颜值甜系房间布置全流程详解 07-30
- 大周列国志全新剧本包西汉剧本包 07-30