如何用 Number.isNaN 准确判定非法数值并排除 undefined 干扰的重点在于把前置条件、操作顺序和容易误判的地方分清楚。
Number.isNaN 更可靠因其不进行类型转换,仅对明确为 NaN 的值返回 true;而全局 isNaN 会强制转数字导致误判,如 isNaN("abc") 返回 true,掩盖真实类型问题。
因为 Number.isNaN 不会做类型转换,只对明确是 NaN 的值返回 true;而全局 isNaN() 会先尝试把参数转成数字,导致 isNaN("abc")、isNaN(undefined) 都返回 true,掩盖了真实类型问题。
常见错误现象:用 isNaN(value) 判定用户输入时,把空字符串、null、undefined 全部当成“非法数值”,但其实你只想捕获真正计算失败产生的 NaN(比如 0/0 或 Math.sqrt(-1))。
Number.isNaN 本身对 undefined、null、""、false 等都返回 false,这是它的天然优势。但要注意:它只管“是不是 NaN”,不管“是不是有效数字”。所以判定“非法数值”必须组合判断。
typeof value === "number"
NaN:Number.isNaN(value)
typeof value === "number" && Number.isNaN(value)
Infinity,额外加 !isFinite(value) 判断(注意 isFinite(NaN) 是 false,所以顺序很重要)比如处理 API 返回的字段,后端可能返回 undefined、null、空字符串或字符串数字。直接用 Number.isNaN(+value) 会引入隐式转换,反而重蹈全局 isNaN 的覆辙。
Number.isNaN(+undefined) → Number.isNaN(NaN) → true(错误放大)Number.isNaN(+"") → Number.isNaN(0) → false(看似安全,但掩盖了空字符串本不该参与数值运算的事实)value != null && typeof value === "number" && Number.isNaN(value)
"123"),应显式调用 parseFloat(value) 并检查结果是否为有限数字,而不是依赖 + 运算符Number.isNaN 是唯一能 100% 精确识别 NaN 的方法,无转换开销;isFinite 虽然也要求参数是数字类型,但它对 NaN 返回 false,不能单独用于检测 NaN;全局 isNaN 在现代代码中基本该被弃用。
Number.isNaN(NaN) → true(唯一正解)isFinite(NaN) → false(不是错,但不等于“它是 NaN”)isNaN(NaN) → true,但 isNaN("foo") 也是 true(语义污染)Number.isNaN 有专门优化,性能略优于 value !== value 这种 hack 写法真正难的不是记住 Number.isNaN,而是意识到:判定“非法数值”从来不是单个函数的事——它取决于你定义的“合法”边界在哪里,而 undefined 往往根本不在那个边界里,它属于数据完整性范畴。