前言
最近在项目代码中,发现了有人使用Number.isNaN()
这个方法,也有人使用isNaN()
这个方法,本着少一事不如多一事的原则,仔细探究了下这两个方法的区别之处。
阅读本文,你将学到:
1. isNaN()的用法
2. Number.isNaN()的用法
3. isNaN()和Number.isNaN()的区别
4. 为什么更推荐使用Number.isNaN()?
1. isNaN()
isNaN
函数是用来确定一个值是否是NaN
,可以在全局直接使用,返回值是一个布尔值true
或false
:
// 基础用法
isNaN(1) // false
isNaN(NaN) // true
但是isNaN
方法有一些怪异的行为,不然也不会有Number.isNaN
函数什么事了:
isNaN(undefined); // true isNaN({}); // true isNaN("37,5") // true isNaN("123ABC") // true isNaN("abc") // true
可以看到,以上的这些isNaN
函数的参数都不是NaN
,怎么还返回true
呢?
MDN的解释是这样的:如果isNaN
函数的参数不是Number
类型, isNaN
函数会首先尝试将这个参数转换为数值,然后才会对转换后的结果是否是NaN
进行判断, 也就是说,isNaN
的参数首先会执行Number()
进行强制转换,然后再去判断是否是NaN
:
isNaN(true) // false 因为Number(true)值为1,而1不是NaN, 所以返回false isNaN(undefined); // true 因为Number(undefined)值为NaN, 所以返回true isNaN({}); // true 因为Number({})值为NaN, 所以返回true isNaN('abc'); // true 因为Number(abc)值为NaN, 所以返回true isNaN(''); // false 因为Number('')值为0, 所以返回false
2. Number.isNaN()
Number.isNaN()
方法确定传递的值是否为 NaN
,并且检查其类型是否为 Number
,它的返回值是布尔类型。它是原来的全局 isNaN()
的更稳妥的版本(注意:ECMAScript 2015
版本才有Number.isNaN()
)。
也就是说,Number.isNaN
函数会先检查参数是不是Number
类型,如果不是,直接会返回false
,只有参数是Number
类型才会去判断是不是NaN
,我们用Number.isNaN
再验证下之前的例子:
// 基本使用
Number.isNaN(NaN) // true
Number.isNaN(1) // false
// 特殊情况
Number.isNaN(true) // false 因为true不是Number类型
Number.isNaN(undefined) // false 因为undefined不是Number类型
Number.isNaN({}) // false 因为{}不是Number类型
Number.isNaN("abc") // false 因为"abc"不是Number类型
Number.isNaN("") // false 因为""不是Number类型
3. 推荐使用Number.isNaN()
通过上述的几个例子可以看到,Number.isNaN
用来判断某个值是否是NaN更像是我们理想型用法,不会产生一些比较怪异的行为,使我们的代码更加的严谨,防止出现bug, 所以在写代码的时候更推荐使用Number.isNaN
这个方法来确定一个值是否是NaN
。