资讯专栏INFORMATION COLUMN

记isNaN与Number.isNaN的区别

Render / 2515人阅读

摘要:有一次项目中发现原来和是有着不一样的判断结果。要了解他们的区别,首先得明确到底是什么在的官方解释中是一个全局代表的值。目前的结论的类型是,这还是有点令人困惑。但从我们上述对的理解来看,这样的判断显然不正确。

有一次项目中发现原来isNaN和Number.isNaN是有着不一样的判断结果。记录一下避免下次踩坑。

要了解他们的区别,首先得明确NaN到底是什么?

在MDN的官方解释中

The global NaN property is a value representing Not-A-Number.

NaN是一个全局代表“Not-A-Number”的值。这样的解释个人觉得还是有些模糊。

在You-Dont-Know-JS中给出了更详细的解释:

NaN literally stands for "not a number", though this label/description is very poor and misleading, as we"ll see shortly. 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."

大家应该也知道:typeof NaN === "number"。

那么结合"invalid number"、"failed number"、"bad number"等描述说明NaN首先得是一个Number类型的值,其次再判断是不是“not a number”。

目前的结论:”not-a-number“的类型是number,这还是有点令人困惑。我们来看下的You-Dont-Know-JS中的场景描述:(怕翻译产生歧义还是直接贴了原文)

NaN is a kind of "sentinel value" (an otherwise normal value that"s assigned a special meaning) that represents a special kind of error condition within the number set. The error condition is, in essence: "I tried to perform a mathematic operation but failed, so here"s the failed number result instead."

再来看一个例子:

var a = 2 / "foo";        // NaN
typeof a === "number";    // true

看到这里相信大家对NaN已经有了较为完整的认识。那么我们如何来判断计算产生的结果是NaN呢?

JS原生提供了isNaN的方法,拿上面的例子来举例:

var a = 2 / "foo";
isNaN(a) // true;

看似没什么问题,但其实isNaN是有着致命的缺陷。它把对NaN的判断就如同字面意思所写的那样:test if the thing passed in is either not a number or is a number。但从我们上述对NaN的理解来看,这样的判断显然不正确。
例如:

var a = 2 / "foo";
var b = "foo";

a; // NaN
b; // "foo"

window.isNaN( a ); // true
window.isNaN( b ); // true

b显然是一个字符串,从我们之前对NaN的定义(NaN的类型是number)来看,b明显不应该是NaN。这个Bug由来许久,所以在es6中提供了替代方案Number.isNaN。我们来看下polyfill就知道他修复了什么问题。

if (!Number.isNaN) {
  Number.isNaN = function(n) {
    return (
      typeof n === "number" &&
             window.isNaN(n)
    );
  };
}

再试验下刚才的例子:

var a = 2 / "foo";
var b = "foo"

Number.isNaN(a); // true
Number.isNaN(b); // false

就能得出我们理想的结果了。

还有一种polyfill非常简单,利用了NaN不等于他自身的特性,NaN是唯一有此特性的值,其他值都等于它们自身(包括undefined和null):

if (!Number.isNaN) {
    Number.isNaN = function(n) {
        return n !== n;
    };
}

最后就是建议大家都使用Number.isNaN来进行判断,如果用了eslint的话,那只写isNaN是会报错的哦。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/107904.html

相关文章

  • Number.isNaN isNaN 区别说起 例子

    摘要:但是跟普通的是的不一样的是,代表这一意义。的没有的情况下,可以采用以下简单来看,就是在原有的基础上增加了一个的判断,因为的是。还有一种更加简单的实现利用了只有不跟自己相等的特性。不过我们可以通过以上方式来解释判断为什么会出现这样的情况了。 例子 大家先看一看下面这个例子, isNaN(NaN); isNaN(A String); isNaN(undefined); isNaN({...

    2bdenny 评论0 收藏0
  • 你可能不知道 NaN 以及 underscore 1.8.3 _.isNaN 一个 BUG

    摘要:全局属性表示的值,顾名思义,就是表示不是一个数字。值得注意的是,是引入的,可以用上面的。而能通过函数的只有。该认为,应该返回。 这篇文章并不在我的 underscore 源码解读计划中,直到 @pod4g 同学回复了我的 issue(详见 https://github.com/hanzichi/underscore-analysis/issues/2#issuecomment-2273...

    huashiou 评论0 收藏0
  • lodash源码分析之NaN不是NaN

    摘要:梁文道暗恋到偷窥本文为读源码的第五篇,后续文章会更新到这个仓库中,欢迎也会同步仓库的更新,地址本篇分析的是函数。源码分析来看下的源码其实的源码其实就只有这么一句。但是返回的是规定和都为时返回的是。 暗恋之纯粹,在于不求结果,完全把自己锁闭在一个单向的关系里面。——梁文道《暗恋到偷窥》 本文为读 lodash 源码的第五篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lo...

    gaomysion 评论0 收藏0
  • ES6之数值扩展

    摘要:二进制和八进制提供了二进制和八进制数值的新的写法,分别用前缀或和或表示。八进制声明八进制的英文单词是,也是以零开始的,然后第二个位置是欧,然后跟上八进制的值就可以了。用来检查一个数值是否为有限的。对于非数值,内部使用方法将其先转为数值。 二进制和八进制 ES6 提供了二进制和八进制数值的新的写法,分别用前缀0b(或0B)和0o(或0O)表示。 二进制声明: 二进制的英文单词是Binar...

    xiguadada 评论0 收藏0
  • js常见基础对象属性方法 (二)

    摘要:常见基础对象属性方法二关于的箭头函数的返回对象的问题箭头函数具有隐式返回的特性。返回值函数累计处理的结果。语句将某个对象添加的作用域链的顶部,如果在中又某个未使用命名空间的变量,跟作用域链中的某个属性同名,则这个变量将指向这个属性值。 js常见基础对象属性方法 (二) 关于es6的箭头函数的返回对象的问题 箭头函数(=>)具有隐式返回的特性。如果某个函数体只有单个表达式,你就可以忽略r...

    Donald 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<