摘要:但是跟普通的是的不一样的是,代表这一意义。的没有的情况下,可以采用以下简单来看,就是在原有的基础上增加了一个的判断,因为的是。还有一种更加简单的实现利用了只有不跟自己相等的特性。不过我们可以通过以上方式来解释判断为什么会出现这样的情况了。
例子
大家先看一看下面这个例子,
isNaN(NaN); isNaN("A String"); isNaN(undefined); isNaN({}); Number.isNaN(NaN); Number.isNaN("A String"); Number.isNaN(undefined); Number.isNaN({});
如果你能很清楚答案,那么这篇文章你可以略过。
不清楚的朋友,我们来慢慢来分析。
答案如下:
isNaN(NaN); // true isNaN("A String"); // true isNaN(undefined); // true isNaN({}); // true Number.isNaN(NaN); // true Number.isNaN("A String"); // false Number.isNaN(undefined); // false Number.isNaN({}); // false
为什么看起来同样的函数,得出的结果为什么不同呢?
NaN 是什么?在解释 NaN 之前,我想先解释下 type/value/variable 这个几个容易混淆的概念,已经很清楚的朋友可以跳过这一小节
type / value / variable 是什么在 JavaScript 中,value一共有七种type
null
undefined
boolean
number
string
object
symbol (ES6新增)
那么,variable是什么呢?就是我们平时 var 之后的声明的那个东西。
type, value, variable 之间的关系可以这么说:variable是存放value的容器,而value是有着type概念的,但是容器variable是没有type的概念的,举个例子
var a = "foo";
容器 variable a 装着 value "foo", value "foo" 的type是string
NaNMDN里面这么描述
The global NaN property is a value representing Not-A-Number.
意思是是说:NaN是一个放在 global(浏览器里是window)对象里的一个value,是一个代表Not-A-Number的value.
意思还是很含糊。
那么我们在看神书《You Don"t Know JS》里的描述
NaN literally stands for "not a number", though this label/description is very poor and misleading, It would be much more accurate to think of NaN as being "invalid number," "failed number," or even "bad number," than to think of it as "not a number."
根据上一个小结的知识,我们知道了,NaN是一个 value, 这个 value 的 type 是 number。
但是跟普通的type是number的value不一样的是,NaN 代表 "Not a number" 这一意义。
那么问题来了,怎么判断一个 value 是不是 NaN 呢?
isNaN()也许有人会说,判断还不容易吗?直接比较不就好了。
NaN === NaN // false
NaN 跟它自己比较会返回false。
所以,我们就需要一个特殊的函数来判断一个value是不是NaN了。
isNaN() 就横空出世了。
我们再回头看一看上面的例子
isNaN(NaN); // true
OK, 成功了,看似很完美,但是接着看以下例子
isNaN("A String"); // true isNaN(undefined); // true isNaN({}); // true
会发现,很明显不是 NaN 的 value 也被误判成 NaN 了。
这个BUG已经存在了20年,从JavaScript最开始就一直存在。很明显当初的设计者,在设计isNaN()的时候,局限了在 "Not a Number" 这一字面意思上了:只要不是number就会返回 true。
于是 ES6 为了弥补这一BUG(而不是修正,因为isNaN存在时间太长,有可能很多功能都是基于这个BUG之上的)引入了 Number.isNaN().
Number.isNaN(NaN); // true Number.isNaN("A String"); // false Number.isNaN(undefined); // false Number.isNaN({}); // false
回头看上面的例子,就明白了修复了什么问题。
Number.isNaN() 的 polyfill没有ES6的情况下,可以采用以下polyfill
if (!Number.isNaN) { Number.isNaN = function(n) { return ( typeof n === "number" && window.isNaN( n ) ); }; }
简单来看,就是在原有 isNaN() 的基础上增加了一个 type 的判断,因为 NaN 的 type 是 number。
还有一种更加简单的实现
if (!Number.isNaN) { Number.isNaN = function(n) { return n !== n; }; }
利用了只有 NaN 不跟自己相等的特性。
顺便吐槽一下MDN的解释,他是这么解释 isNaN() 的
You could think of isNaN as:
var isNaN = function(value) { return Number.isNaN(Number(value)); }
他是在ES6新函数Number.isNaN()的基础上,去解释旧函数isNaN()的。
不过我们可以通过以上方式来解释判断 isNaN() 为什么会出现
isNaN("A String"); // true isNaN(undefined); // true isNaN({}); // true
这样的情况了。
作者微博
作者博客
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/92016.html
摘要:有一次项目中发现原来和是有着不一样的判断结果。要了解他们的区别,首先得明确到底是什么在的官方解释中是一个全局代表的值。目前的结论的类型是,这还是有点令人困惑。但从我们上述对的理解来看,这样的判断显然不正确。 有一次项目中发现原来isNaN和Number.isNaN是有着不一样的判断结果。记录一下避免下次踩坑。 要了解他们的区别,首先得明确NaN到底是什么? 在MDN的官方解释中 The...
摘要:常见基础对象属性方法二关于的箭头函数的返回对象的问题箭头函数具有隐式返回的特性。返回值函数累计处理的结果。语句将某个对象添加的作用域链的顶部,如果在中又某个未使用命名空间的变量,跟作用域链中的某个属性同名,则这个变量将指向这个属性值。 js常见基础对象属性方法 (二) 关于es6的箭头函数的返回对象的问题 箭头函数(=>)具有隐式返回的特性。如果某个函数体只有单个表达式,你就可以忽略r...
摘要:的数字类型是基于标准实现的,该标准也被称为浮点数使用的是双精度即位进制由于数字值可以使用对象进行封装,因此数字值可以调用中的方法。 数组 和其他语言不同,在JavaScript中,数组可以拥有不同值类型,可以使字符串,数字,对象,还可以是数组(多维数组就是这样形成的). 声明数组后,可以直接通过索引的方式进行赋值: var arr = []; arr.length; //0 ...
摘要:今天要讲的,是我从的源码实现文件中学到的几个很基础,却又容易被忽略的知识点。在函数式编程中,函数是一等公民,它可以只是根据参数,做简单的组合操作,再作为别的函数的返回值。所以,阅读源码,是一种很棒的重温基础知识的方式。 showImg(https://segmentfault.com/img/bVbpTSY?w=750&h=422); 前言 上一篇文章 「前端面试题系列8」数组去重(1...
摘要:返回布尔值,表示参数字符串是否在原字符串的头部。模板字符串之中还能调用函数。其他对字符串还有许多扩展,例如对字符表示的扩充以及为字符串提供了遍历方法详情请点击正则的扩展构造函数在中,构造函数的参数有两种情况。 ES6对各种基本类型都做了扩展,内容有些多,本章节挑选比较重要的扩展说明。 1 字符串的扩展 1.1 includes(), startsWith(), endsWith() 传...
阅读 2410·2021-11-25 09:43
阅读 1245·2021-11-24 09:39
阅读 741·2021-11-23 09:51
阅读 2382·2021-09-07 10:18
阅读 1840·2021-09-01 11:39
阅读 2776·2019-08-30 15:52
阅读 2589·2019-08-30 14:21
阅读 2850·2019-08-29 16:57