Object.is()是唯一能同时解决NaN!==NaN和+0===-0问题的原生方法,严格按IEEE 754位模式执行SameValue算法:NaN自等、±0不等,其余同===;适用于负零检测、NaN确认及含NaN数组去重,但不适用于对象深比较或高频简单比较。

Object.is() 是 JavaScript 中唯一能同时修复 NaN !== NaN 和 +0 === -0 这两类精度漏洞的原生方法。它不靠类型转换,也不妥协语义,而是严格按 IEEE 754 位模式执行 SameValue 算法 —— 这让它成为处理浮点边界值的“精准标尺”。
为什么 NaN 和 ±0 会出问题
JavaScript 的 === 在设计上遵循“抽象相等”的工程取舍:
-
NaN === NaN返回 false:语言规范强制规定 NaN 是“永不等于自身”的值,导致去重、缓存、状态比对全部失效 -
+0 === -0返回 true:虽然二者在 IEEE 754 中符号位不同(+0 是0x00000000,-0 是0x80000000),但===忽略符号位,掩盖了真实差异
Object.is 如何精准判定
它的判断逻辑只有三步,清晰且可预测:
- 若两个值都是
NaN→ 返回 true - 若一个是
+0、另一个是-0→ 返回 false - 其余所有情况,行为与
===完全一致
这意味着你不需要额外记忆例外规则——只要记住“NaN 自己认自己,±0 各自为政”,就覆盖了全部关键差异。
实际怎么用才不踩坑
重点不在“能不能用”,而在“在哪必须用”:
-
检测负零:写
Object.is(x, -0),别用x === -0(因为0 === -0也成立) -
确认 NaN 结果:比如
const res = Math.sqrt(-1); if (Object.is(res, NaN)) { ... },比isNaN()更可靠(不触发类型转换) -
数组去重含 NaN:Set 不行(内部用 SameValueZero),得手写过滤:
arr.filter((item, i) => arr.findIndex(v => Object.is(v, item)) === i)
什么场景不该硬套 Object.is
它不是万能替代品:
- 对象或数组内容比较仍返回 false(和
===一样),不递归深比,别指望它代替_.isEqual - 日常字符串/数字判断用
===更快更自然,Object.is 约慢 10%~15%,高频循环里没必要升维打击 - 如果业务上把 ±0 当作同一概念(如 UI 显示归零),反而该用
===或显式归一化(x === 0 ? 0 : x)










