NaN 不等于 NaN 是因 IEEE 754 标准规定其表示未定义结果,无确定数值含义;JavaScript 遵循该标准,故 NaN === NaN 和 NaN == NaN 均为 false,仅 Object.is(NaN, NaN) 返回 true。

JavaScript 中 NaN === NaN 和 NaN == NaN 都返回 false,这是唯一一个不等于自身的值。
为什么 NaN 不等于 NaN?
这是 IEEE 754 浮点数标准的规定:NaN 表示“不是一个有效数字”,其本质是未定义或不可表示的计算结果(如 0/0、Math.sqrt(-1))。既然它没有确定的数值含义,就无法与其他任何值(包括另一个 NaN)进行有意义的相等比较。
JavaScript 完全遵循该标准,所以:
-
NaN === NaN→ false -
NaN == NaN→ false -
Object.is(NaN, NaN)→ true(例外,ES6 引入的严格同值比较)
如何正确判断一个值是否为 NaN?
不能用 == 或 ===,应使用专用方法:
立即学习“Java免费学习笔记(深入)”;
-
isNaN(value):会先尝试把 value 转为数字再判断,有误判风险(如isNaN("hello")→ true,但isNaN(" ")→ false) -
Number.isNaN(value):更可靠,只对真正是NaN的值返回 true,不进行类型转换(推荐) -
value !== value:利用 NaN 是唯一自比较不等于自身的特性,可作为底层判断技巧(但可读性差,一般不建议直接用)
实际开发中的注意事项
在做数组去重、对象属性比对、缓存键生成等涉及相等性判断的场景时,若数据可能含 NaN,需特别处理:
- 用
Number.isNaN()替代=== NaN - 需要“深度相等”时(如 Lodash 的
_.isEqual),它们内部已对 NaN 做了特殊兼容 - 自定义比较逻辑中,若要让两个 NaN 视为相等,可显式添加判断:
Number.isNaN(a) && Number.isNaN(b)
Object.is 提供了更语义化的 NaN 相等性
Object.is() 是 ES6 新增的三元相等判断,行为上介于 == 和 === 之间,关键区别包括:
-
Object.is(NaN, NaN)→ true -
Object.is(+0, -0)→ false(而===认为它们相等) - 适合用于需要精确值对比的场景,比如 React 的
useMemo或React.memo的依赖比较


















