前言
本文和大家分享一个前几天写代码踩的坑,笔者在业务逻辑中需要对一个值进行 NaN
的判断,由于笔者的不严谨,使用了isNaN
,从而引起了Bug
,也正是因为这个,笔者才知道了 isNaN
和 Number.isNaN
的区别,如果你认为这俩没区别,觉得 isNaN
是历史遗留的全局变量,后面又加到 Number
上的话,建议你接着往下看。如果你知道他们的区别,可以划走了。👻
笔者将从以下两个方面来描述这个知识点:
- 什么是
NaN
。 isNaN
和Number.isNaN
的区别是什么。
什么是NaN
JS
中的 NaN
,是 Not a Number
的缩写,代表一个值 或者 一个表达式的值 不是一个数字。它有以下几个特点:
- 不等于任何其他值,包括它本身。这意味着
NaN
与任何值的比较都会返回false
,包括NaN
本身。
- 它是全局作用域中的一个变量。
Number.NaN
和NaN
是同一个东西,有相同的特性,只不过一个是全局变量;一个是Number
上的属性。但是它俩也不能划等号,毕竟NaN
自己都不等于自己。NaN
涉及数学运算,通常情况下都会返回NaN
,但是还有例外,看下图:NaN
涉及关系比较(>
,<
,>=
,<=
)时,都返回false
。
什么情况下会得到NaN
呢?
- 显式将非
NumBer
类型转为Number
类型,比如Number('aaa')
。 - 在调用一些需要数字类型参数的
API
时,可能API
内部会做转换,一旦无法转为数字,可能就返回了NaN
,比如Math.abs('aaa')
。 - 等等......
那在平时开发中,为了保证我们写的代码逻辑运行正常,就可能需要对 NaN
判断,接下来我们就来看下判断 NaN
的两个 API
有啥不同。
isNaN
和 Number.isNaN
的区别
首先,这俩 API
都能够用于判断 NaN
,这一点从 API
的名字就能看出,然后各位看图总结不同的地方:
不同点:
Number.isNaN
是直接拿参数与NaN
去比,也就是说,你一定要传NaN
进去才返回true
。至于怎么比的,咱也不知道,反正不是===
,因为NaN
的特性------自己不等于自己。isNaN
会先尝试将参数转换成数字,如果可以转换成数字,则返回false
;否则返回true
。
咱们不妨来讨论一下,Number.isNaN
内部的实现,肯定不是:
js
Number.isNaN = (target) => target === NaN // 自己不等于自己
我猜可能是:
js
// 因为只有传 `NaN` 进去才返回 `true`,而 NaN 是 Number 类型
// 再加上 `NaN + '' === 'NaN'`
// 也许是对的
Number.isNaN = (target) => Object.prototype.toString.call(target) === '[object Number]' && target+'' === 'NaN'
总结
本文主要内容为:
NaN
的特性isNaN
和Number.isNaN
的区别,一句话总结:Number.isNaN
只有传NaN
进去才返回true
;isNaN
传NaN
或者不能转化为Number
的都会返回true
。
以后咱们还是不要使用isNaN
为好!
如果本文对你有一点点帮助,点个赞支持一下吧,你的每一个【赞
】都是我创作的最大动力 ^_^
。