非常教程

JavaScript参考手册

全球对象 | Global Objects

isNaN

isNaN()函数用来确定一个值是否为NaN 。注:isNaN函数内包含一些非常有趣的规则;你也可以通过ECMAScript 2015/ES6 中定义的Number.isNaN()或者 可以使用typeof来判断该值是否为一个非数字。

语法

isNaN(value)

参数

Value要被检测的值。

返回值

true如果给定的值是NaN; 否则,false

描述

isNaN功能的必要性

与JavaScript中所有其他可能的值不同,不可能依赖于相等运算符(==和===)来确定值是否 NaN与否,因为两者都是NaN == NaNNaN === NaN求值的false。因此,isNaN功能是必要的。

NaN的来源

当算术运算导致undefinedunrepresentable时, 将生成 NaN 值。这些不一定代表溢出。NaN 还会从尝试强制转换为非数值的值, 而这些值没有任何原始数值可用。

例如,零除零导致一个NaN- 但其他数字除以零不。

令人费解的怪异行为

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

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

可以把isNaN看做:

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

示例

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

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

// strings
isNaN('37');      // false: "37" is converted to the number 37 which is not NaN
isNaN('37.37');   // false: "37.37" is converted to the number 37.37 which is not NaN
isNaN('123ABC');  // true:  parseInt("123ABC") is 123 but Number("123ABC") is NaN
isNaN('');        // false: the empty string is converted to 0 which is not NaN
isNaN(' ');       // false: a string with spaces is converted to 0 which is not NaN

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

// This is a false positive and the reason why isNaN is not entirely reliable
isNaN('blabla');   // true: "blabla" is converted to a number. 
                   // Parsing this as a number fails and returns 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)The definition of 'isNaN' in that specification.

Standard

ECMAScript 2015 (6th Edition, ECMA-262)The definition of 'isNaN' in that specification.

Standard

ECMAScript Latest Draft (ECMA-262)The definition of 'isNaN' in that specification.

Living Standard

浏览器兼容性

Feature

Chrome

Edge

Firefox (Gecko)

Internet Explorer

Opera

Safari

Basic support

(Yes)

(Yes)

(Yes)

(Yes)

(Yes)

(Yes)

Feature

Android

Chrome for Android

Edge

Firefox Mobile (Gecko)

IE Mobile

Opera Mobile

Safari Mobile

Basic support

(Yes)

(Yes)

(Yes)

(Yes)

(Yes)

(Yes)

(Yes)

JavaScript

JavaScript 是一种高级编程语言,通过解释执行,是一门动态类型,面向对象(基于原型)的解释型语言。它已经由ECMA(欧洲电脑制造商协会)通过 ECMAScript 实现语言的标准化。它被世界上的绝大多数网站所使用,也被世界主流浏览器( Chrome、IE、FireFox、Safari、Opera )支持。JavaScript 是一门基于原型、函数先行的语言,是一门多范式的语言,它支持面向对象编程,命令式编程,以及函数式编程。它提供语法来操控文本、数组、日期以及正则表达式等,不支持 I/O,比如网络