zoukankan      html  css  js  c++  java
  • 你应该知道的JavaScript中NaN的秘密

      NaN,不是一个数字,是一种特殊的值来代表不可表示的值,使用typeof或其他任何与之比较的处理方式,‘NaN’则会引起一些混乱,

      一些操作会导致NaN值的产生。这里有些例子:

    Math.sqrt(-2)
    Math.log(-1)
    0/0
    parseFloat('foo')

      对于很多JavaScript的初学者来说,它的第一个陷阱是调用typeof时返回结果的通常是你想不到的:

    console.log(typeof NaN);   // 'number'

      这情情况下,NaN并不意味着是一个数字,它的类型是数字。明白吗?

      保持冷静,因为下面还有很多混乱的地方。让我们比较两个NaN:

    var x = Math.sqrt(-2);
    var y = Math.log(-1);
    console.log(x == y);      // false

      也许这是因为我们没有使用严格等价(===)操作?显然不是。

    var x = Math.sqrt(-2);
    var y = Math.log(-1);
    console.log(x === y);      // false

      好吧!难道是因为这两个NaN是从不同的操作产生出来的?那么这样...

    var x = Math.sqrt(-2);
    var y = Math.sqrt(-2);
    console.log(x == y);      // false

      再疯狂一点

    var x = Math.sqrt(-2);
    console.log(x == x);      // false

      直接比较两个NaN呢?

    console.log(NaN === NaN); // false

      因为有很多方法来表示一个非数字,所以一个非数字不会等于另一个为NaN的非数字,它还是有一定道理的。不过这也是我为什么时而崩溃的原因:

    这是对你的提醒,NaN的意思是“不为NaN".
    — Ariya Hidayat (@AriyaHidayat)

      为了解决这个问题,本来我打算向ECMAScript 7提交该方案的

    GarlicNaN != NaN

      但是当然,解决方案现在已经有了。

      让我们认识一下全局函数isNaN:

    console.log(isNaN(NaN));      // true

      唉,不过 isNaN() 也有它自己的很多缺陷呀:

    console.log(isNaN('hello'));  // true
    console.log(isNaN(['x']));    // true
    console.log(isNaN({}));       // true

      这样又产生 了很多不同的解决方案。其中一个是利用 了NaN的非反射性质(例如, 看看 Kit Cambridge 的笔记)

    var My = {
      isNaN: function (x) { return x !== x; }
    }

      另外一个例子是先检查值的类型(防止强制转换):

    My.isNaN = function(x) { return typeof x === 'number' && isNaN(x)};

      不过幸运的是,在即将到来的ECMAScript 6中, 有一个Number.isNaN() 方法提供可靠的NaN值检测。(随便说下,你已经可以在最新版的Chrome和firefox中使用这个方法了)。在2014年4月的规范草稿中,有着如下记载:

    当传入一个数字参数并调用 Number.isNaN 时,会进行以下几步:

    1. 如果Type(number) 不是数字, 返回 false.
    2. 如果数字是NaN, 返回true.
    3. 其他情况,返回false.

      换句话说,只有在参数是真正的NaN时,才会返回true 

    console.log(Number.isNaN(NaN));            // true
    console.log(Number.isNaN(Math.sqrt(-2)));  // true
    console.log(Number.isNaN('hello'));        // false
    console.log(Number.isNaN(['x']));          // false
    console.log(Number.isNaN({}));             // false

      下一次,当你需要处理NaN时,要格外小心了。

      附: Poetro 的评论

      这是 IEEE 754 定义的NaN标准, 跟JavaScript无关。

    "在计算中, NaN, 代表一个非数字, 是用来呈现未定义(undefined)和不可呈现(unrepresentable)的数据类型, 尤其是在浮点计算中。"
    "与NaN的比较会一直返回一个无序的结果,甚至跟它自己比较。"

      原文 ariya.ofilabs.com

  • 相关阅读:
    王者齐聚!Unite 2017 Shanghai 日程讲师全揭晓
    微软在.NET官网上线.NET 架构指南频道
    期待微软平台即服务技术Service Fabric 开源
    Visual Studio 20周年软件趋势随想
    .NET 十五岁,谈谈我眼中的.NET
    API网关Ocelot 使用Polly 处理部分失败问题
    互联网背景下知识半衰期这么短,如何学习?
    CentOS 7 上面安装PowerShell
    搭建consul 集群
    Entity Framework Core 实现MySQL 的TimeStamp/RowVersion 并发控制
  • 原文地址:https://www.cnblogs.com/ranzige/p/3760915.html
Copyright © 2011-2022 走看看