isNaN
isNaN
isNaN()
函数用来确定一个值是否为NaN
。注:isNaN
函数内包含一些非常有趣的规则;你也可以通过ECMAScript 2015/ES6 中定义的Number.isNaN()
或者 可以使用typeof
来判断该值是否为一个非数字。
语法
isNaN(value)
参数
Value
要被检测的值。
返回值
true
如果给定的值是NaN
; 否则,false
。
描述
isNaN功能的必要性
与JavaScript中所有其他可能的值不同,不可能依赖于相等运算符(==和===)来确定值是否
NaN
与否,因为两者都是NaN == NaN
和NaN === NaN
求值的false
。因此,isNaN
功能是必要的。
NaN的来源
当算术运算导致undefined
或 unrepresentable
时, 将生成 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) |