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()是返回真或假。
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
发表评论:
◎请发表你卖萌撒娇或一针见血的评论,严禁小广告。