ES6+ Number.isFinite()&Number.isNaN()
1. 前言
在 ES5 中,全局下的 isFinite () 和 isNaN () 两种 方法 存在类型转换,对最终的判断结果存在歧义。ES6 在 Number 对象上,新提供了 Number.isFinite () 和 Number.isNaN () 两个 方法 ,更加健壮地进行数值的判断,接下来让我看看这两种 方法 。
2. Number.isFinite()
在 ES5 中有全局的 isFinite() 函数 用来判断被传入的参数值是否为 一个 有限的数值,如果参数是字符串,会首先转为 一个 数值,然后在进行验证。
isFinite ( ) ; // false isFinite ( ) ; // false isFinite ( - ) ; // false isFinite ( ) ; // true isFinite ( ) ; // true isFinite ( '2e64' ) ; // true isFinite ( "0" ) ; // true
上面的 代码 可以看出,字符串也会被先转为数值再进行判断,而 ES6 Number 对象上提供的 isFinite() 更健壮,和全局的 isFinite() 函数 相比,这个 方法 不会强制将 一个 非数值的参数转换成数值,这就意味着, 只有 数值类型 的值,且是有穷的(finite),才返回 true 。
Number . isFinite ( ) ; // false Number . isFinite ( ) ; // false Number . isFinite ( - ) ; // false Number . isFinite ( ) ; // true Number . isFinite ( ) ; // true Number . isFinite ( '2e64' ) ; // false Number . isFinite ( '0' ) ; // false
3. Number.isNaN()
在 JavaScript 中与其它的值不同, NaN 不能通过相等操作符(== 和 ===)来判断 ,因为 NaN == NaN 和 NaN === NaN 都会返回 false 。 因此,判断 一个 值是不是 NaN 是有必要的。
3.1 NaN 值的产生
当算术运算的结果返回 一个 未定义的或无法表示的值时, NaN 就产生了。但是, NaN 并不一定用于表示某些值超出表示范围的情况。
将某些非数值强制转换为数值的时候,会得到 NaN 。
0 除以 0 会返回 NaN —— 但是其他数除以 0 则不会返回 NaN。
上一节 我们知道可以使用 Number() 方法 进行类型转换,下面列举被强制类型转换为 NaN 的例子:
Number ( undefined ) // NaN Number ( 'undefined' ) // NaN Number ( 'string' ) // NaN Number ( { } ) // NaN Number ( '10,3' ) // NaN Number ( '123ABC' ) // NaN Number ( new Date ( ) . toString ( ) ) // NaN
上面的例子可以看出,很多值在强制类型转换下转为 NaN ,针对这样的值去进行判断无疑是有问题的,下面我们来看下 isNaN () 的问题。
3.2 isNaN () 的问题
默 认情况全局下存在 方法 isNaN () 用了判断是否为 NaN 值,它要求接收的是 数值类型 的参数,但是当参数不是 Number 类型, isNaN 函数 会首先尝试将这个参数转换为数值,然后才会对转换后的结果是否是 NaN 进行判断。
实例:
isNaN ( ) ; // true isNaN ( undefined ) ; // true isNaN ( 'undefined' ) // true isNaN ( { } ) ; // true isNaN ( true ) ; // false isNaN ( null ) ; // false isNaN ( ) ; // false // strings isNaN ( "37" ) ; // false: 可以被转换成数值37 isNaN ( "37.37" ) ; // false: 可以被转换成数值37.37 isNaN ( "37,5" ) ; // true isNaN ( '123ABC' ) ; // true: parseInt("123ABC")的结果是 123, 但是Number("123ABC")结果是 NaN isNaN ( "" ) ; // false: 空字符串被转换成0 isNaN ( " " ) ; // false: 包含空格的字符串被转换成0 // dates isNaN ( new Date ( ) ) ; // false isNaN ( new Date ( ) . toString ( ) ) ; // true isNaN ( "imooc" ) // true: "blabla"不能转换成数值 // 转换成数值失败, 返回NaN
结合上面 NaN 是如何产生的例子的结果可以看出,使用 isNaN 来判断返回的是 true ,这显然不是我们想要的结果。针对这样的问题,ES6 做了修补,下面我们看 ES6 中的 isNaN 方法 。
3.3 Number.isNaN () 详情
ES6 提供了 Number.isNaN(x) ,通过这个 方法 来 检测变量 x 是否是 一个 NaN 将会是一种可靠的做法,它不会对所判断的值进行强制类型转换。
Number . isNaN ( ) ; // true Number . isNaN ( Number . ) ; // true Number . isNaN ( / ) // true // 下面这几个如果使用全局的 isNaN() 时,会返回 true。 Number . isNaN ( "NaN" ) ; // false,字符串 "NaN" 不会被隐式转换成数字 NaN。 Number . isNaN ( undefined ) ; // false Number . isNaN ( 'undefined' ) ; // false Number . isNaN ( { } ) ; // false Number . isNaN ( "blabla" ) ; // false Number . isNaN ( true ) ; // false Number . isNaN ( null ) ; // false Number . isNaN ( ) ; // false Number . isNaN ( "37" ) ; // false Number . isNaN ( "37.37" ) ; // false Number . isNaN ( "" ) ; // false Number . isNaN ( " " ) ; // false
通过上面的实例,基本覆盖了现有程序的所有情况,不会出现使用全局下的 isNaN() 多带来的问题。所有推荐使用 Number.isNaN(x) 方式来判断是否是 NaN 。在 不支持 Number.isNaN 函数 情况下,可以通过表达式 (x != x) 来 检测变量 x 是不是 NaN 会更加可靠。
4. 小结
本节中传统的全局 方法 isFinite() 和 isNaN() 的区别在于,传统 方法 先 调用 Number () 将非数值的值转为数值,再进行判断,而这两个新 方法 只对数值有效, Number.isFinite() 对于非数值一律返回 false, Number.isNaN() 只有对于 NaN 才返回 true ,非 NaN 一律返回 false 。
查看更多关于ES6+ isFinite()&isNaN()的详细内容...