首页>前端教程>JavaScript教程

JavaScript基础5:NaN和isNaN到底是啥?

NaN和isNaN(),还有ES6提供的Number.isNaN(),真的把脑袋都绕晕了,觉得计算机的世界真的好笨,人看一眼就知道的事情,它们要有一套各种转换逻辑才能得出结论。好吧,其实它们的逻辑都是人设计的,最终还是人笨了 : )

一、什么是NaN?

number数据类型包括有效数字和一个NaN,所以NaN是number数据类型,但是它表示自己“不是一个数字(not a number)”。感觉NaN好像一个哭鼻子的表情 >_<有木有?

什么时候出现NaN?通常是计算失败,或者转换别的数据类型成数字的时候失败,就爆出NaN了。

 0*Infinity;  //   NaN 
 0/0;  //NaN
 Infinity/Infinity;  //NaN

上面的表达式硬是算不出来,只能给一个NaN了。

二、isNaN的检测机制

isNaN()用来检测当前的参数是不是不是有效数字,不是有效数字返回true,是有效数字,返回false。

1、对原始值的检测机制

原始数据类型就会调用Number()先转一下,能转成数字的,就进行计算,不能转成数字,算不出来的,就返回NaN。

在很多计算中,就包含着这种隐式转换。

2+"3";// 23,+表示连接了,不会调用Number()转换。就+不行,其他数学运算符都可以转。
6/"3";// 2 ,先Number("3")->3,再计算6/3=2。
7*"12px";//NaN,Number("12px")->NaN,当字符中出现任何一个非有效数字字符,转不出来。任何数字和NaN运算,都是NaN。
2>true;// true,Number(true)->1,Number(false)->0 
2>null;//true,Number(null)->0
2+undefined;//NaN, Number(undefined)->NaN

2、对引用类型的检测机制

如果是引用数据类型的转换,则需要先调用toString()转换成字符串,再调用Number()转换成数字。

注意:toString()属于Object对象的方法, 所以任何一个对象都可以使用该方法,但是不同的对象又重写了该方法,以适应自身的需求。比如Number.toString(2)是返回二进制数字。Boolean.toString()是返回真或假。

JavaScript toString() 函数详解

isNaN({});// true   ({}).toString()->"[object object]"->Number("[object object]")->NaN
isNaN([1,2]);// true  [1,2].toString()->"1,2"->Number("1,2")->NaN
isNaN(function myname(){});// true  (function myname(){}).toString()->"function myname(){}"->Number("function myname(){}")->NaN

三、NaN!==NaN

在js中,唯一一个自身不等于自身的神奇存在。因为NaN是Number上的一个不可配置,不可写的静态属性,只是一种表示方式,表明这是一个无效的数字,因此不能参与运算,也就无法与自身比较。

所以不能用一个变量和NaN判断是否相等来检测变量是不是不是一个有效的数字,而应该使用isNaN来实现:

if(!isNaN(num)){
 console.log("这是一个有效数字");

}

但是这也会有问题,因为isNaN()函数有隐式转换,所以即使参数不是一个真正的数字,而是一个空字符串或者空数组,也会认为是一个有效的数字。

所以ES6提供了一个Number.isNaN()来判断一个值是不是严格意义上等于NaN。

注意:Number.isNaN()和isNaN()不是一样的。isNaN()是一个全局函数。

四、Number.isNaN()

该方法确定值是不是为NaN。ES6新增的一个方法。

验证过程:

1、判断参数类型,不是Number类型,返回false。

2、参数是不是NaN,是返回true。

3、其它返回false。

它和isNaN()的区别在于,Number.isNaN()没有任何转换,而isNaN()会先用Number()进行隐式转换之后再检测。

Number.isNaN()对于任何不是Number类型的值都不会返回true。

Number.isNaN(123) //false
Number.isNaN(-1.23) //false
Number.isNaN(5-2) //false
Number.isNaN(0) //false
Number.isNaN('123') //false
Number.isNaN('Hello') //false
Number.isNaN('2005/12/12') //false
Number.isNaN('') //false
Number.isNaN(true) //false
Number.isNaN(undefined) //false
Number.isNaN('NaN') //false
Number.isNaN(NaN) //true
Number.isNaN(0 / 0) //true

这个函数就耿直多了,是NaN就返回true,不用担心那些乱七八糟偷偷摸摸的隐式转换了。

遗憾的就是,要Edge12以上才支持,IE嘛,肯定不行了。

所以,可以根据它自身不等于自身的特性自定义一个函数来判断。

function isNAN(value){
return value!==value;
}
isNAN(NaN);// true
isNAN("1234");//false
isNAN(true);//false
isNAN([]);// false
isNAN({});// false
isNAN(null);//false
isNAN("");//false
isNAN(0/0);//true

点赞


0
保存到:

相关文章

Top