你不知道的JavaScript(四)数值

JS中只有一种数值类型,即number。不管是整数还是小数都属于number类型,事实上JS并不区分小数和整数。

<div>
    <script type="text/javascript">
        var num1 = 40.00;
        var num2 = 40;
        alert(num1 === num2);//alert true
    </script>
</div>

我们对40.00和40使用运算符===进行比较发现返回true,也就是说二者完全相同。和绝大多数流行的脚本语言一样,JS语言的number类型基于IEEE 754标准实现。IEEE 754定义了如何在计算机中存储和表示浮点数,关于它的细节,有兴趣的朋友可以参考维基百科对IEEE 754的说明。

IEEE 754:http://en.wikipedia.org/wiki/IEEE_754-1985

下面来看一下数值类型的一些不常见的书写方式。

    <script type="text/javascript">
        var num1 = 0.42;
        var num2 = .42;
        alert(num1 === num2);
        var num3 = 42.0;
        var num4 = 42.;
        alert(num3 === num4);
    </script>

小数点前面为0时,可以省略,.42也是合法的数字。小数点后面全部为0时,也可以省略小数点后面的部分。.42和42.虽然是合法的数字,但是为了代码的可读性,我们通常不会这样写。

再来看看JS数值比较中,比较容易让人产生困惑的问题:

    <script type="text/javascript">
       alert((0.1 + 0.2) === 0.3); //false
    </script>

我们使用(0.1 + 0.2) === 0.3,按照正常的编程逻辑,该表达式应该返回true才对,但这里偏偏返回的是false。这是什么原因呢?

首先需要明确的一点是,这并不是JavaScript语言的问题,所有使用IEEE 754标准实现浮点数的语言都要面对这个问题。下面笔者就来解释一下这个原因,大家都知道任何两个数(例如0.1和0.2)之间都有无数多个数,每一个数都在计算机中表示出来是不可能的。对于一个浮点数运算,计算机并不能精准的计算出它的结果,而是尽可能的接近它。也就是说(0.1 + 0.2)的计算结果并不是精确的等于0.3,可能是0.30000000000000004,所以二者也就不可能相等。针对这种情况我们通常会这样处理,如果两个浮点数之差的绝对值小于某一个范围,我们就认为这两个浮点数相等。

有了这些理论基础,我们可以通过自定义函数解决浮点数比较问题,代码如下:

       if (!Number.EPSILON) {
           Number.EPSILON = Math.pow(2,-52);
       }
       function numbersCloseEnoughToEqual(n1,n2) {
           return Math.abs( n1 - n2 ) < Number.EPSILON;
       }
       var a = 0.1 + 0.2;
       var b = 0.3;
       alert( numbersCloseEnoughToEqual( a, b ));//true

接着介绍一下number类型中几个特殊的值:

1.NaN,它表示该值不是一个数值,是不是很奇怪,看下面的代码:

    <script type="text/javascript">
        var num = 1/"abc";
        alert(num);//NaN
        alert(typeof num);//number
        alert(num === NaN);//false
        alert(isNaN(num));//true
    </script>

我们用数字除以一个字符串,结果为NaN,它表明该计算结果不是一个数值。使用typeof操作符查看类型,确实是number类型。接下来”奇怪”的事情又来了,我们用===运算符和NaN进行比较,发现结果又为false。这个问题ECMAScript规范中有提到过,NaN不等于任何一个NaN,我们可以使用JS内置函数isNaN来判断一个值是否是NaN。
2.Infinity与-Infinity,Infinity表示正无穷大,-Infinity表示负无穷大。

    <script type="text/javascript">
        var num1 = 100/0;
        var num2 = -100/0;
        alert(num1);//Infinity
        alert(num2);//-Infinity
        alert(typeof num1);//number
        alert(typeof num2);//number
        alert(num1 + num2);//NaN
        alert(num1 + num1);//Infinity
        alert(num2 + num2);//-Infinity
    </script>

大多数语言中,一个数与0相乘都会抛出运行时异常,例如Java中会抛出java.lang.ArithmeticException异常,但是JavaScript中则不会,正数与零相除的结果为正无穷Infinity,负数与零相除的结果为-Infinity,它们两个都是number类型的值,Infinity与-Infinity相加结果为NaN,两个Infinity相加结果还是Infinity,两个-Infinity相加也还是-Infinity。相减、相乘和相除的情况读者可以自己写代码测试。

演示代码地址:https://github.com/rongbo-j/you-dont-know-js

原文地址:https://www.cnblogs.com/lanzhi/p/6468821.html