面试题:isNaN 和 Number.isNaN 函数有什么区别?

isNaN()Number.isNaN() 都是 JavaScript 中用于检查一个值是否为 NaN(Not-a-Number)的函数,但它们的行为有本质区别,尤其是在处理非数字类型的输入时。


一、isNaN()(全局函数)

行为:

  • 会先尝试将传入的值转换为数字,然后再判断转换后的结果是否为 NaN
  • 这意味着它不仅检查“是否是 NaN”,还会检查“是否能转换为有效数字”。

示例:

isNaN(NaN)          // true  ← 正常情况
isNaN("hello")      // true  ← "hello" 转为数字是 NaN
isNaN(undefined)    // true  ← undefined 转为数字是 NaN
isNaN({})           // true  ← {} 转为数字是 NaN
isNaN("123")        // false ← "123" 转为 123,是有效数字
isNaN(true)         // false ← true 转为 1,是有效数字

问题:

  • 它会将任何无法转换为有效数字的值都判定为 true,而不仅仅是 NaN
  • 这可能导致误判,因为它混淆了“值本身就是 NaN”和“值无法转换为数字”两种情况。

二、Number.isNaN()(ES6 引入)

行为:

  • 不会进行类型转换
  • 只有当传入的值本身就是 NaN 时,才返回 true
  • 如果传入的值不是 NaN(即使它无法转换为数字),也返回 false

示例:

Number.isNaN(NaN)       // true  ← 值本身就是 NaN
Number.isNaN("hello")   // false ← "hello" 不是 NaN,只是无法转换
Number.isNaN(undefined) // false ← undefined 不是 NaN
Number.isNaN({})        // false ← {} 不是 NaN
Number.isNaN("123")     // false ← "123" 不是 NaN
Number.isNaN(123)       // false ← 123 不是 NaN

三、关键区别对比

输入值isNaN()Number.isNaN()说明
NaNtruetrue两者一致
"hello"truefalseisNaN 转换后为 NaNNumber.isNaN 不转换
undefinedtruefalse同上
{}truefalse同上
"123"falsefalse两者一致
123falsefalse两者一致
truefalsefalse两者一致

四、为什么 isNaN() 有“缺陷”?

isNaN() 是在早期 JavaScript 中定义的,它的设计初衷是检查“某个值是否代表一个无效的数字”,但由于它会强制转换类型,导致它实际上检查的是“某个值是否无法转换为有效数字”。

这在某些场景下可能有用,但通常我们只想知道一个值是否真的是 NaN


五、如何选择?

场景推荐函数原因
检查一个值是否真的是 NaNNumber.isNaN()更精确,不进行类型转换,语义清晰
检查一个值是否能转换为有效数字isNaN()Number.isNaN(Number(value))isNaN() 会自动转换,但语义模糊;更推荐显式转换后检查
现代开发优先使用 Number.isNaN()它是 ES6 标准,行为更可靠

推荐的现代做法:

// 检查是否为 NaN
if (Number.isNaN(value)) {
  console.log("value is NaN");
}

// 检查是否能转换为有效数字
if (Number.isNaN(Number(str))) {
  console.log("str cannot be converted to a valid number");
}

六、Polyfill(兼容旧环境)

在不支持 Number.isNaN() 的旧环境中,可以这样模拟:

Number.isNaN = Number.isNaN || function(value) {
  return typeof value === "number" && isNaN(value);
};

或者更精确地(因为 NaN !== NaN):

Number.isNaN = Number.isNaN || function(value) {
  return value !== value; // 只有 NaN 不等于自身
};

总结

函数行为推荐使用场景
isNaN()先转换类型,再判断。任何无法转为有效数字的值都返回 true避免使用,语义不清晰
Number.isNaN()不转换类型。只有当值本身就是 NaN 时才返回 true推荐,精确、可靠

核心区别isNaN() 会进行类型转换,而 Number.isNaN() 不会。在现代 JavaScript 开发中,应优先使用 Number.isNaN()

THE END
喜欢就支持一下吧
点赞15 分享