You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
function isNaN(value) {
// An `NaN` primitive is the only value that is not equal to itself.
// Perform the `toStringTag` check first to avoid errors with some
// ActiveX objects in IE.
return isNumber(value) && value != +value;
}
1 介绍
NaN的定义是:
表面说自己不是number,但是本意是一个number类型(真讨厌~~):
它的一些属性:
还有一个重要特性就是它与任何东西都不相等包括他自己,即
NaN != NaN
。其他的,
NaN
与0
,false
,""
,null
,undefined
都属于Falsy值。一般情况也较少用到,但是由于它独特的性质会在遇到它时非常棘手。比如在数组去重的时候,
NaN
的出现常常会给你带来不必要的麻烦。所以,当你需要处理NaN
的时候,你迫切的需要一个判断NaN
的方法,由于NaN
的特殊性,原生JS库就有判断的方法。我作为一个初学者,目前其实很少遇到处理
NaN
,刷Lodash
时,看着自己实现的NaN觉得很多不足,找了一些方法,算是有点收获,于是笔记记一下以免再次掉坑里。2 实现
在我网上找解决方法的时候发现很多判断
NaN
的方法很可能都是错的,基本上包含了所有的博客类或者社区类文章,看了整整一天没发现好文章。不是我错了,是全世界错了?还是我错了?带着疑问我步步推进。isNaN()
这是大家都避免过的坑了,也是很久之前的面试题。听到
NaN
,第一个大坑就是这个。isNaN()
作为官方提供的全局方法应该是很可靠的,开始我都是用这个,官方的人比我牛逼多了,想的肯定比我多,稍微试一下:官方的函数言简意赅,好像还不错,但是随着我测试多了起来发现不对:
为什么是这样呢?经过我的查找,因为它传入的值,首先会通过
Number()
函数转化为Number
类型再进行NaN
的判断(Confusing special-case behavior),至于为什么转化官方也有说明(我没看)。所以导致传入的值是不可以被转化为数字的情况时,无法判断他是不是NaN
。即类似'a123'
,经过Number()
函数转化后返回结果是NaN
,再判断是就NaN
了。所以不能用这个函数判断某个值是NaN
。Number.isNaN()
因为转化
Number
的关系导致isNaN
变成大坑,于是我先判断它是不是Number
类型不就可以了。网上很多文章在发现isNaN()
是个大坑后,基本都是采取这种解决方式,写出的结果大概如下:通过
isNumber
确定它是Number
类型,然后再进行判断。官方再发现isNaN()
的问题后也进行了修补,就是Number.isNaN()
实现方式基本一样:这次基本上就修补了那些
isNaN()
的怪异行为,测试一下确实如此:开心,一切都是那么的完美了!
在推出
Number.isNaN()
后,仿佛一切都得到了解决。在我刷lodash前我也是这么认为的,官方的修补应该是不会出错,那么判断NaN
是不是就是Number.isNaN
就可以搞定了呢?_.isNaN()
刷Lodash总能让我得到许多惊喜。Lodash的
_.isNaN
函数有个官方示例非常有趣,如下:好像没什么特别,于是我立即用
Number.isNaN()
对比一下,得出了一些结果:明显的不同,不由的看了Lodash的实现,是这样的:
函数中间夹杂着注释,在Lodash我目前只见过这一个,显然它描述着为什么他们会采取这种方式来验证
NaN
。首先还是判断它的类型是Number
,接着进行NaN的判断,NaN判断的方式还是用它自己不等于自己的特性;==
的目的在于这个判断需要进行隐式转换;至于为什么后面有个+
号,+
作用是为了转换,例如+'123'
会把字符串自动转化为123
,但是由于对==的不熟悉,找了半天都头痛,对于==
的转换还是推荐一个回答 ,就不要强求了,我只认===
。所以在某种意义上好像解决了目前所有的问题。但是我还有点点想法,关于这个判断,因为
NaN
其中一个特性就是不会等于自己,但是new Number(NaN)
是可以等于自己的,其实不难理解,因为这时候他成为了对象,一个引用类型,指向同一个地址肯定是相等的,这个时候的NaN
像是Number的一个属性,这时候的NaN
是不是NaN
呢?我觉得还是一个 疑问号,按照官方理解应该不是,但是常用库lodash修复了就意味着认可他是。总结
NaN真是一个特殊的值,通过它反映JS存在的问题的写照。JS存在很多坑点,但是能有这么强大的生命力。在其他语言这种类型判断还要想半天感觉很奇怪,也是JS的“特性”吧。
假如你可以保证只使用基本类型时,可以利用不等于自身的方法:
假如你需要更健壮的方法,或者说你不知道什么类型的情况下,绝大部分情况下都推荐使用系统自带的
Number.isNaN()
。当然,也可以自己实现一个类似的:假如你使用了包装类型,或者想判断包装类型的
NaN
那么需要使用Lodash库,或者自己写一个类似的:这里的
isNumber
推荐使用原型的方法进行判断。得到教训:
最后好像终于告一段落了,这一个方法看到大家实现的奇怪,于是自己扎进去看了一下,醒来发现自己已经落后了?
周围的人很多时候都劝我不要搞这些牛角尖问题。但是它就像一小个山顶,很少人去,去了的人告诉我没什么意思,其他没去过的人看来太过于浪费时间和精力,往往这时候去爬着试试会感觉很有趣,中间过程会让人迷茫亦或憧憬于山顶的景象,但是很可能吃力的爬到山顶却发现那里什么都没有,一切也没啥意思,仿佛失去了意义,但是我不会后悔去爬任何一座小山顶,因为那中间的过程才是我想要的东西。
参考链接:
你可能不知道的 NaN 以及 underscore 1.8.3 _.isNaN 的一个 BUG
Javascript 中 == 和 === 区别是什么
Number.isNaN()
The text was updated successfully, but these errors were encountered: