nan 不等于任何值包括自身,因其本质是“无法表示的数值结果”,ieee 754 标准规定所有涉及 nan 的相等比较均返回 false,以明确标示计算失效。

NaN 在 JavaScript 数值比较中不等于任何值,包括它自己——这是它最核心的反直觉表现。这种行为不是 bug,而是严格遵循 IEEE 754 浮点数标准的设计选择,目的是明确标示“计算失效”,避免无效值被误当作有效数字参与后续逻辑。
为什么 NaN === NaN 返回 false?
因为 NaN 的本质不是“某个具体数字”,而是“无法表示的数值结果”。IEEE 754 规定:所有涉及 NaN 的相等比较(==、===、>、=、
- 它不满足自反性(a === a),是 JS 中唯一一个不等于自身的原始值
- 底层原因在于 NaN 实际是一类值的集合(如 0/0 产生的 NaN 和 Number("abc") 产生的 NaN 可能有不同位模式),语言无法定义它们之间“相等”的语义
- 如果允许 NaN === NaN 为 true,就可能掩盖数据异常,比如财务计算中本该报错的 NaN 被当成合法值继续累加
常见比较操作的结果一览
以下行为容易引发误判,需特别注意:
- NaN == NaN → false
- NaN === NaN → false
- NaN > 0、NaN = 0、NaN → 全部 false
- NaN == undefined、NaN == null、NaN == false → 全部 false
- [NaN].indexOf(NaN) → -1(用 === 查找,找不到)
- [NaN].includes(NaN) → true(ES2016 起,includes 内部使用的是 SameValueZero 算法,对 NaN 特殊处理)
如何正确检测 NaN?
绝不能用 == 或 === 判断。推荐两种安全方式:
- Number.isNaN(val):最推荐。只对真正 NaN 返回 true,不会把空字符串、null、undefined 等转成数字后误判
- Object.is(val, NaN):ES6 引入的同值相等,能准确识别 NaN(Object.is(NaN, NaN) → true),也区分 +0 和 -0
- 避免使用全局 isNaN():它会先尝试把参数转成数字,导致 isNaN(" ")、isNaN({}) 都返回 true,干扰判断
实际开发中的影响与规避建议
NaN 很容易在数据流中静默传播,比如数组求和、平均值、图表渲染时未过滤 NaN,结果直接变成 NaN。
- 做数值聚合前,先用 Number.isFinite() 筛掉 NaN 和 Infinity
- 表单输入校验时,对用户输入调用 parseFloat 或 Number 后,立刻用 Number.isNaN 检查
- 使用 Lodash 的 _.isEqual 时要知道它内部对 NaN 做了特殊兼容(_.isEqual(NaN, NaN) → true),但原生 === 不行,混用要注意一致性
- 调试时可打印 typeof val + ' ' + String(val) 辅助识别:typeof NaN 是 "number",但 String(NaN) 是 "NaN"
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











