isNaN()

isNaN() 函数用来确定一个值是否为Number.isNaN() 来判断。

语法

isNaN(value)

参数

value
要被检测的值。

返回值

如果给定值为 NaN则返回值为true;否则为false

描述

isNaN 函数的必要性

与 JavaScript 中其他的值不同,NaN不能通过相等操作符(== 和 ===)来判断 ,因为 NaN == NaNNaN === NaN 都会返回 false。 因此,isNaN 就很有必要了。

NaN值的产生

当算术运算返回一个未定义的或无法表示的值时,NaN就产生了。但是,NaN并不一定用于表示某些值超出表示范围的情况。将某些不能强制转换为数值的非数值转换为数值的时候,也会得到NaN

例如,0 除以0会返回NaN —— 但是其他数除以0则不会返回NaN

令人费解的怪异行为

如果isNaN函数的参数不是Number类型, isNaN函数会首先尝试将这个参数转换为数值,然后才会对转换后的结果是否是NaN进行判断。因此,对于能被强制转换为有效的非NaN数值来说(空字符串和布尔值分别会被强制转换为数值0和1),返回false值也许会让人感觉莫名其妙。比如说,空字符串就明显“不是数值(not a number)”。这种怪异行为起源于:"不是数值(not a number)"在基于IEEE-754数值的浮点计算体制中代表了一种特定的含义。isNaN函数其实等同于回答了这样一个问题:被测试的值在被强制转换成数值时会不会返回IEEE-754​中所谓的“不是数值(not a number)”。

下一个版本的ECMAScript (ES2015)包含Number.isNaN()函数。通过Number.isNaN(x)来检测变量x是否是一个NaN将会是一种可靠的做法。然而,在缺少Number.isNaN函数的情况下, 通过表达式(x != x) 来检测变量x是否是NaN会更加可靠。

一个isNaN的 polyfill 可以理解为(这个polyfill利用了NaN自身永不相等于自身这一特征 ):

var isNaN = function(value) {
    var n = Number(value);
    return n !== n;
};

示例

isNaN(NaN);       // true
isNaN(undefined); // true
isNaN({});        // true

isNaN(true);      // false
isNaN(null);      // false
isNaN(37);        // false

// strings
isNaN("37");      // false: 可以被转换成数值37
isNaN("37.37");   // false: 可以被转换成数值37.37
isNaN("37,5");    // true
isNaN('123ABC');  // true:  parseInt("123ABC")的结果是 123, 但是Number("123ABC")结果是 NaN
isNaN("");        // false: 空字符串被转换成0
isNaN(" ");       // false: 包含空格的字符串被转换成0

// dates
isNaN(new Date());                // false
isNaN(new Date().toString());     // true

isNaN("blabla")   // true: "blabla"不能转换成数值
                  // 转换成数值失败, 返回NaN

有用的特殊行为

有许多方式来看待isNaN():如果isNaN(x)返回false,那么x在任何算数表达式中都不会使表达式等于NaN;如果返回true,x会使所有算数表达式返回NaN。这就意味着,在JavaScript中,isNaN(x)==true等价于x-0=NaN(在JavaScript中 x-0 == NaN 总是返回false,所以你不用去测试它)。实际上, isNaN(x)isNaN(x - 0),isNaN(Number(x))Number.isNaN(x - 0),和Number.isNaN(Number(x)) 的返回值都是一样的 并且在JavaScript中isNaN(x)是这些表达式中最短的表达。

举个例子,可以利用这个特殊行为来检测函数的参数是可运算的(可以像number一样进行加减乘除等运算)。如果不可运算,则可赋予这个参数一个默认的值或其他合适的内容。这样,就可以得到一个隐式转换参数值的函数,而这得益于Javascript的全功能性。

例子

function increment(x) {
  if (isNaN(x)) x = 0;
  return x + 1;
};

// The same effect with Number.isNaN():
function increment(x) {
  if (Number.isNaN(Number(x))) x = 0;
  return x + 1;
};

// In the following cases for the function's argument x,
// isNaN(x) is always false, although x is indeed not a
// number, but can be used as such in arithmetical
// expressions
increment("");            // 1: "" is converted to 0
increment(new String());  // 1: String object representing an empty string is converted to 0
increment([]);            // 1: [] is converted to 0
increment(new Array());   // 1: Array object representing an empty array is converted to 0
increment("0");           // 1: "0" is converted to 0
increment("1");           // 2: "1" is converted to 1
increment("0.1");         // 1.1: "0.1" is converted to 0.1
increment("Infinity");    // Infinity: "Infinity" is converted to Infinity
increment(null);          // 1: null is converted to 0
increment(false);         // 1: false is converted to 0
increment(true);          // 2: true is converted to 1
increment(new Date());    // returns current date/time in milliseconds plus 1

// In the following cases for the function's argument x,
// isNaN(x) is always false and x is indeed a number
increment(-1);            // 0
increment(-0.1);          // 0.9
increment(0);             // 1
increment(1);             // 2
increment(2);             // 3
// ... and so on ...
increment(Infinity);      // Infinity

// In the following cases for the function's argument x,
// isNaN(x) is always true and x is really not a number,
// thus the function replaces it by 0 and returns 1
increment(String);            // 1
increment(Array);             // 1
increment("blabla");          // 1
increment("-blabla");         // 1
increment(0/0);               // 1
increment("0/0");             // 1
increment(Infinity/Infinity); // 1
increment(NaN);               // 1
increment(undefined);         // 1
increment();                  // 1

// isNaN(x) is always the same as isNaN(Number(x)),
// but the presence of x is mandatory here!
isNaN(x) == isNaN(Number(x))  // true for every value of x, including x == undefined,
                              // because isNaN(undefined) == true and Number(undefined) returns NaN,
                              // but ...
isNaN() == isNaN(Number())    // false, because isNaN() == true and Number() == 0

规范

Specification Status Comment
ECMAScript 1st Edition (ECMA-262) Standard Initial definition.
ECMAScript 5.1 (ECMA-262)
isNaN
Standard
ECMAScript 2015 (6th Edition, ECMA-262)
isNaN
Standard
ECMAScript Latest Draft (ECMA-262)
isNaN
Draft

浏览器兼容性

Update compatibility data on GitHub
Desktop Mobile Server
Chrome Edge Firefox Internet Explorer Opera Safari Android webview Chrome for Android Firefox for Android Opera for Android Safari on iOS Samsung Internet Node.js
isNaN Chrome Full support 1 Edge Full support 12 Firefox Full support 1 IE Full support 3 Opera Full support Yes Safari Full support Yes WebView Android Full support 1 Chrome Android Full support 18 Firefox Android Full support 4 Opera Android Full support Yes Safari iOS Full support Yes Samsung Internet Android Full support 1.0 nodejs Full support Yes

Legend

Full support  
Full support

相关链接