Number.isNaN 与 isNaN 的区别是什么?

1,711 阅读4分钟

在 JavaScript 中,NaN(Not-a-Number)代表一个特殊的非数字值。当你需要检查一个值是否为 NaN 时,通常会借助 isNaN() 函数。然而,随着 ECMAScript 6(ES6)的推出,Number.isNaN()方法被引进,提供了一种更加精确的方式来判断一个值是否真的是NaN。尽管这两者都与 NaN 打交道,但它们在行为上有着明显的区别。本文旨在深入探究 Number.isNaNisNaN 之间的不同。

NaN 的特性

  1. 任何与NaN进行数学运算的结果都将是NaN:无论您如何尝试与NaN进行数学运算,输出总是NaN
NaN + 5; // 返回 NaN
NaN - 2; // 返回 NaN
NaN * 10; // 返回 NaN
  1. NaN与任何值都不等同,包括它自己:  即便是与另一个NaN比较,结果也是false
NaN === NaN; // 返回 false
NaN == NaN;  // 返回 false

注:为了有效地检查一个值是否为NaN,我们应当使用Number.isNaN(),而非相等运算符。

isNaN 函数

首先,让我们来了解一下 isNaN 函数。isNaN 函数用于检查一个变量是否为 NaN,其基本用法是:

isNaN(value)

如果传入的 valueNaNisNaN 就返回 true;否则返回 false。然而,isNaN 有其局限性,导致其在某些场景下的行为不符合预期。原因在于 isNaN 会试图将传入的值转换成数字,而这种转换可能导致误判。

isNaN 的问题

isNaN 的主要问题在于它的自动类型转换行为,即在判断前试图将值转换为数值类型。这种行为会导致一些非NaN值被误判为NaN

isNaN("hello"); // 返回 true,但 "hello" 不是 NaN
isNaN(undefined); // 返回 true,但 undefined 不是 NaN
isNaN({}); // 返回 true,但空对象 {} 不是 NaN

为了解决这个问题,ECMAScript 6 引入了 Number.isNaN 方法。

Number.isNaN 方法

Number.isNaN 是 Number 类的静态方法,提供了一种严格和精确的校验手段,用以判断一个值是否真的是NaN,其用法如下:

Number.isNaN(value)

isNaN 不同,Number.isNaN 不会对输入进行类型转换,而是直接严格校验该值是否为 NaN

Number.isNaN 的优势

Number.isNaN 的主要优势在于它更精确,不会对传入的值进行类型转换。这使得它能够准确判断一个值是否是 NaN,而不会因类型转换而导致误判。

Number.isNaN("hello"); // 返回 false,"hello" 不是 NaN
Number.isNaN(undefined); // 返回 false,undefined 不是 NaN
Number.isNaN({}); // 返回 false,空对象 {} 不是 NaN

兼容性

需要注意的是,Number.isNaN 是在 ECMAScript 6(ES6)中引入的,因此它在较旧的浏览器中可能不受支持。为了在不支持 Number.isNaN 的环境中使用它,你可以使用一个简单的 polyfill:

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

这段 polyfill 代码会检查当前环境是否已定义 Number.isNaN 方法。如果未定义,就会为 Number对象添加这个方法。在这个版本的实现中,它首先检查传入值是否为数值类型,然后使用全局 isNaN 函数来判断该数值是否是 NaN。这种方法有效地模拟了 Number.isNaN 的行为,从而确保即使在不支持ES6的环境下,代码也能正确运行。

结论

在 JavaScript 中,处理特殊值 NaN 需要特别的注意,因为它与其他数值有着不同的行为特性。尤其是当涉及到检测一个值是否为 NaN 时,选择正确的方法至关重要。isNaNNumber.isNaN为我们提供了两种选项,但它们在行为上有着明显不同。

  • isNaN 由于它的自动类型转换行为,可能会导致非 NaN 值被误判为 NaN。因此,在需要判断一个值是否真实地为 NaN 时,它可能并不是最佳选择。
  • Number.isNaN 提供了一种更精确、不涉及类型转换的方法来判断一个值是否为 NaN。它解决了 isNaN 在某些情况下的不准确问题,是推荐使用的方法。

对于在旧版 JavaScript 环境中要使用 Number.isNaN 的开发者,polyfill 提供了一个实用的后备选项。这确保了 Number.isNaN 的优势——精准性和可靠性——可以在各种运行环境中得以保留和利用。

综上所述,了解和正确使用 isNaNNumber.isNaN 有助于开发者更好地控制程序逻辑,避免潜在的错误和误解。