JavaScript中的 NaN 与 isNaN

NaN

NaN 即 Not a Number ,不是一个数字。 在 JavaScript 中,整数和浮点数都统称为 Number 类型 。除此以外,Number 类型还有一个很特殊的值,即 NaN 。它是 Number 对象上的一个静态属性,能够经过 Number.NaN 来访问 。 html

console.log(Number.NaN); // NaN

在 ECMAScript v1 和其后的版本中,还能够用预约义的全局属性 NaN 代替 Number.NaN 。spa

console.log(NaN); // NaN

在如下两种场景中,可能会产生 NaN 值 。htm

【1】表达式计算

一个表达式中若是有减号 (-)、乘号 (*) 或 除号 (/) 等运算符时,JS 引擎在计算以前,会试图将表达式的每一个分项转化为 Number 类型(使用 Number(x) 作转换)。若是转换失败,表达式将返回 NaN 。对象

100 - '2a' ; // NaN
'100' / '20a'; // NaN
'20a' * 5 ; // NaN
undefined - 1; // NaN, Number(undefined) == NaN
[] * 20 ; // 0, Number([]) == 0
null - 5; // -5, Number(null) == 0 

而 加号 (+) 不会将其两边的变量转化为 Number 类型,这是由于JS表达式的执行顺序是按照运算符的优先级从左到右依次进行的,若是加号 (+) 两边的变量都是 Number 类型时,才会作数字相加运算,若是其中有一个变量是字符串,则会将两边都做为字符串相加。blog

5 + 4 + '6' = '96';
1 + '2' + 3 =  '123'

【2】类型转换

直接使用 parseInt,parseFloat 或 Number 将一个非数字的值转化为数字时,表达式返回 NaN 。ip

'abc' - 3   // NaN
parseInt('abc')  // NaN
parseFloat('abc') // NaN
Number('abc')    // NaN

对于 数字+字符 的值,其转化结果会有所不一样:字符串

Number('123abc'); // NaN
parseInt('123abc'); // 123
parseInt('123abc45'); // 123
parseFloat('123.45abc');// 123.45

Number 转换的是整个值,而不是部分值;parseInt 和 parseFloat 只转化第一个无效字符以前的字符串。 另外,一元加操做符也能够实现与 Number 相同的做用。 get

+ '12abc'; // NaN
+ '123'; // 123
+ '123.78'; // 123.78
+ 'abc'; // NaN

所以,当一个字符串不能被 Number、parseInt 或 parseFloat 成功转换时,就返回 NaN,表示该字符串没法被识别为数字类型,这是一个异常状态,并非一个确切的值。 博客

isNaN

isNaN() 是一个全局方法,它的做用是检查一个值是否能被 Number() 成功转换 。 若是能转换成功,就返回 false,不然返回 true 。io

isNaN(NaN)    // true 不能转换
isNaN('123')   // false 能转换
isNaN('abc')    // true 不能转换
isNaN('123ab')   // true 不能转换
isNaN('123.45abc') // true 不能转换

能够看出,isNaN() 没有办法判断某个值自己是否为 NaN 。若是想要知道某个值自己是否为 NaN,能够利用 NaN 不等于自身 这一特性来判断。

function selfIsNaN(value){
    return value !== value
}

另外,ES6 在 Number 对象上也提供了 isNaN()  方法,和全局方法 isNaN() 不一样的是,它用于判断某个值自己是否为 NaN,而不须要进行类型转换。

Number.isNaN('123'); // false 自己不是NaN
Number.isNaN('abc'); // false 自己不是NaN
Number.isNaN(NaN); // true 自己是NaN

 

原创发布 @一像素  2016 博客园 

 

【参考资料】

[1] 详解 ECMAScript 数据类型

相关文章
相关标签/搜索