- JavaScript重难点实例精讲
- 周雄
- 1302字
- 2021-04-03 20:56:06
1.2.3 isNaN()函数与Number.isNaN()函数对比
Number类型数据中存在一个比较特殊的数值NaN(Not a Number),它表示应该返回数值却并未返回数值的情况。
NaN存在的目的是在某些异常情况下保证程序的正常执行。例如0/0,在其他语言中,程序会直接抛出异常,而在JavaScript中会返回“NaN”,程序可以正常执行。
NaN有两个很明显的特点,第一个是任何涉及NaN的操作都会返回“NaN”,第二个是NaN与任何值都不相等,即使是与NaN本身相比。
NaN == NaN; // false
在判断NaN时,ES5提供了isNaN()函数,ECMAScript 6(后续简称ES6)为Number类型增加了静态函数isNaN()。
既然在ES5中提供了isNaN()函数,为什么要在ES6中专门增加Number.isNaN()函数呢?两者在使用上有什么区别呢?
1. isNaN()函数
首先我们来看看isNaN()函数的作用,它用来确定一个变量是不是NaN。NaN是一个Number类型的数值,只不过这个值无法用真实的数字表示。
如果传递的参数是Number类型数据,可以很容易判断是不是NaN。如果传递的参数是非Number类型,它返回的结果往往会让人费解。
例如下面判断一个空对象{}的代码。
isNaN({}); // true
空对象{}明明不是一个NaN的数据,应该返回的是“false”,为什么会返回“true”呢?
这里我们首先要知道NaN产生的条件,一方面是在数据运算时,返回了一个无法表示的数值,例如0 / 0就会返回“NaN”。有一点需要注意的是除了0 / 0,其他数据除以0都返回“Infinity”。
另一方面是在需要做强制类型转换时,某些数据不能直接转换为数值类型,就会返回“NaN”,例如1 - 'a' = NaN,因为字符串'a'无法参与数值运算。
而isNaN()函数正好会进行数据的类型转换,它在处理的时候会去判断传入的变量值能否转换为数字,如果能转换成数字则会返回“false”,如果无法转换则会返回“true”。
接下来就通过下面这些代码来测试一下。
isNaN(NaN); // true isNaN(undefined); // true isNaN({}); // true isNaN(true); // false,Number(true)会转换成数字1 isNaN(null); // false,Number(null)会转换成数字0 isNaN(1); // false isNaN(''); // false,Number('')会转换为成数字0 isNaN("1"); // false,字符串"1"可以转换成数字1 isNaN("JavaScript"); // true,字符串"JavaScript"无法转换成数字 // Date类型 isNaN(new Date()); // false isNaN(new Date().toString()); // true
Date是一种比较特殊的类型,当我们调用new Date()函数生成的实例并转换为数值类型时,会转换为对应的时间戳,例如下面的代码。
Number(new Date()); // 1543333199705
因此isNaN(new Date())会返回“false”。
而当我们调用了toString()函数时,返回的是一串字符串表示的时间,无法转换成数值类型,因此isNaN(new Date().toString())会返回“true”。
2. Number.isNaN()函数
既然在全局环境中有isNaN()函数,为什么在ES6中会专门针对Number类型增加一个isNaN()函数呢?
这是因为isNaN()函数本身存在误导性,而ES6中的Number.isNaN()函数会在真正意义上去判断变量是否为NaN,不会做数据类型转换。只有在传入的值为NaN时,才会返回“true”,传入其他任何类型的值时会返回“false”。
我们可以通过以下这些代码做测试。
Number.isNaN(NaN); // true Number.isNaN(undefined); // false Number.isNaN(null); // false Number.isNaN(true); // false Number.isNaN(''); // false Number.isNaN(123); // false
上面代码运行后,除了传入NaN会返回“true”以外,传入其他的值都会返回“false”。如果在非ES6环境中想用ES6中的isNaN()函数,该怎么办呢?我们有以下兼容性处理方案。
// 兼容性处理 if(!Number.isNaN) { Number.isNaN = function (n) { return n !== n; } }
因为在所有类型的数据中,如果一个变量和自身作比较,只有在变量值为NaN时才会返回“false”,其他情况都是返回“true”。
所以n !== n返回“true”,只有在n为NaN的时候才成立。
3. 总结
isNaN()函数与Number.isNaN()函数的差别如下。
· isNaN()函数在判断是否为NaN时,需要先进行数据类型转换,只有在无法转换为数字时才会返回“true”;
· Number.isNaN()函数在判断是否为NaN时,只需要判断传入的值是否为NaN,并不会进行数据类型转换。