nan 不等于自身是 ieee 754 标准规定,并非 bug;应使用 number.isnan() 检测,避免 === 判断;计算前校验、兜底默认值、过滤 nan;object.is() 可使 nan === nan 为 true。

JavaScript 中 NaN 确实不等于自身(NaN === NaN 为 false),这是唯一一个不满足自反性的值。这不是 bug,而是 IEEE 754 标准的规定——因为“未定义”或“不可表示”的计算结果之间无法判定相等。处理它关键不是“绕过”,而是用正确方式识别和应对。
用 Number.isNaN() 或 isNaN() 检测 NaN
别用 == 或 === 判断是否为 NaN:
-
value === NaN永远是false,完全无效 -
isNaN(value)可用,但会强制转换(如isNaN("abc")返回true,isNaN("123")却是false) - 推荐用
Number.isNaN(value):只对真正是NaN的值返回true,不进行类型转换,更安全准确
在数值计算前主动过滤或校验
很多 NaN 来自无效运算(如 Math.sqrt(-1)、0 / 0、parseInt("abc"))。可在参与比较或累加前拦截:
- 对输入做类型+有效性检查:
if (typeof x === 'number' && !Number.isNaN(x)) { /* 安全使用 */ } - 用空值默认值兜底:
const safeNum = Number.isNaN(num) ? 0 : num; - 数组聚合时跳过 NaN:
[1, 2, NaN, 4].filter(Number.isFinite).reduce((a, b) => a + b, 0);
比较逻辑中避免直接用 === 匹配 NaN
如果业务需要“把 NaN 当作相同值来分组或去重”,就得自定义逻辑:
- 例如去重数组:
[1, NaN, 2, NaN].filter((v, i, a) => a.indexOf(v) === i || (Number.isNaN(v) && a.slice(0, i).some(Number.isNaN))) - 更清晰写法是抽象判断函数:
const equalsNaNOrValue = (a, b) => Number.isNaN(a) && Number.isNaN(b) || a === b; - 排序时若需 NaN 排末尾:
arr.sort((a, b) => Number.isNaN(a) ? 1 : Number.isNaN(b) ? -1 : a - b);
用 Object.is() 统一处理特殊相等性
Object.is() 是 ES6 引入的严格相等判断,它把 NaN === NaN 视为 true,同时还能区分 +0 和 -0:
-
Object.is(NaN, NaN)→true -
Object.is(+0, -0)→false(而===认为它们相等) - 适合需要语义上“完全一致”的场景,比如深比较、缓存 key 判断
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











