NaN是JavaScript中类型为"number"却表示计算失败的特殊值,产生于无效数学运算、强制类型转换失败等场景;推荐用Number.isNaN检测,避免isNaN误判,且不可用==或===比较NaN。

NaN(Not-a-Number)是 JavaScript 中一个特殊的数值类型,它表示“本应是数字但无法表示为有效数字”的结果。它不是错误,而是一个合法的值,类型为 "number",却在语义上代表计算失败或类型转换异常。
NaN 的常见产生原因
NaN 通常出现在以下几类操作中:
- 数学运算无效:如
0 / 0、Math.sqrt(-1)、Math.log(-1) - 强制类型转换失败:如
parseInt("abc")、Number("hello")、+"foo" - 非数值参与算术运算:如
"a" - 1、null ** -1(ES2023 中0 ** -1是Infinity,但null ** -1会先转为0再报错?实际是NaN,因Number(null)是0,但0 ** -1是Infinity;真正触发 NaN 的是像undefined * 2或true + {}这类模糊转换) - 显式赋值:
let x = NaN;或调用NaN全局属性(不推荐)
检测 NaN 的常规方法及其局限性
JavaScript 提供了多种判断 NaN 的方式,但每种都有其适用边界和陷阱:
-
value !== value:利用 NaN 是唯一不等于自身的值这一特性。✅ 可靠,✅ 无需依赖全局对象,❌ 但可读性差、语义隐晦,不适合团队协作代码 -
isNaN(value):会先尝试将参数转为数字再判断。❌ 对" "、""、{}等返回true(因为转数字后是0或NaN),存在误判;❌ 不区分“真 NaN”和“可转为 NaN 的非数字” -
Number.isNaN(value):✅ ES6 引入,仅当参数是NaN且类型为"number"时返回true。这是目前最推荐的检测方式。❌ 但它不会对字符串"NaN"、undefined等做类型转换,即Number.isNaN("NaN") === false
为什么不能用 == 或 === 判断 NaN?
因为根据 IEEE 754 标准,NaN 被定义为不等于任何值——包括它自己。所以:
立即学习“Java免费学习笔记(深入)”;
-
NaN === NaN→false -
NaN == NaN→false -
Object.is(NaN, NaN)→true(✅ 唯一能正确比较 NaN 相等性的内置方法)
实用建议:如何安全处理可能为 NaN 的值
在真实项目中,与其反复检测 NaN,不如从源头预防或封装健壮逻辑:
- 对用户输入或 API 数据做校验后再参与计算,例如用
typeof x === "number" && !isNaN(x)(注意:这里isNaN仍有缺陷,更稳妥的是typeof x === "number" && isFinite(x)) - 使用
isFinite()可同时排除NaN、Infinity和-Infinity,适合多数“需要普通数字”的场景 - 写工具函数统一处理,例如:
const isValidNumber = (v) => typeof v === "number" && isFinite(v); - 在 TypeScript 中启用
strictNullChecks并配合类型守卫,可大幅减少运行时 NaN 风险









