5. Number

ECMAScript 有两种内置的数值类型:Number 和 BigInt

按照 ECMAScript 标准的规定,JavaScript 中的所有算术都要使用双精度浮点算术来完成。

1. 通用知识

关于双精度浮点数,需要理解以下内容:

  1. 浮点数的四类常量arrow-up-right:最大最小正数、最大最小安全整数、最小间隔、特殊值

内容较多,所以分成多篇在《计算机基础》arrow-up-right的浮点数章节中进行详细的介绍。

2. Number 类型

JavaScript 里的 Number 类型是一个双精度 64-bit 二进制格式 IEEE 754 值arrow-up-right,这意味着它能表示小数,但在存储上会有一些限制,比如算术上需要四舍五入arrow-up-right精度上只保留大约 17 个有效数字arrow-up-right

a double-precision 64-bit binary format IEEE 754 value

2.1 浮点数

在 JavaScript 代码中,字面量 35 本质上是个浮点数而不是整数,在日常使用中是没有单独的整数类型的。现在有了个 BigInt 类型,但它并不是为了在日常使用中取代 Number 的。

除了表示浮点数之外,Number 类型还有三个符号值:+Infinity-InfinityNaN(Not a Number)。

2.2 范围

  • 能存储 [210742^{-1074}, 210242^{1024}] 之间的正浮点数和 [-210242^{1024}, -210742^{-1074}] 之间的负浮点数:超出此范围的数值会被替换成 ±Infinity±0

  • 但只能安全地存储 ±(2532^{53}- 1) 范围内的整数:超出此范围的数值,将不能被安全地表示

关于这两个范围涉及的具体值的解释和相关常量,详见双精度浮点数中的四类常量arrow-up-right

2.3 NaN

NaN,Not a Number,非数值。

当算术运算的结果不能表示为数值时,通常会遇到 NaN。以下五类操作会返回 NaN

  1. 无法解析的数值,比如 parseInt('hello'), Number(undefined)

  2. 结果不是实数的数学运算,比如 Math.sqrt(-1)

  3. 操作数是 NaN,比如 7**NaN

  4. 不确定形式,比如 0*Infinity, undefined+undefined

  5. 对于不是加法的运算,只要涉及到了字符串就会返回 NaN,比如 'foo'/2

NaN 是全局对象上的一个属性。在现代浏览器中,NaN 是不可配置、不可写的。

通常,我们很少在程序中使用 NaN 变量或是去覆盖它,当然也不建议这么做。

2.4 字面量表示

Number 可以用字面量表示,比如 1e3, 08, 0755, 0o755, 0b111, 0x7fe 等。

这部分内容,详见数值的字面量表示arrow-up-right

3. Number 对象

Number 对象是 Number 原始值的对象包装器,用来表示和操作数值类型。

3.1 构造器

  1. new Number() 返回 Number 对象,搭配 new 关键字作为构造函数

  2. Number() 返回 Number 数值,直接当函数用可做类型转换,如果不能转换就返回NaN

Number() 作为函数使用,很常见。如下:

Number() 加关键词 new 当做构造函数使用,很少见,也不推荐。原因如下:

3.2 静态属性

  1. 最大正数和最小正数

    • Number.MAX_VALUE 可表示的最大正数

    • Number.MIN_VALUE 可表示的最小正数,即最接近零的正数(实际上并不为零)

  2. 最大安全整数和最小安全整数

    • Number.MAX_SAFE_INTEGER 最大安全整数,2532^{53} - 1

    • Number.MIN_SAFE_INTEGER 最小安全整数,-(2532^{53} - 1)

  3. 正负无穷大(溢出时返回)

    • Number.NEGATIVE_INFINITY 表示负无穷大的特殊值

    • Number.POSITIVE_INFINITY 表示无穷大的特殊值

  4. Number.EPSILON 两个可表示的数值之间的最小间隔

  5. Number.NaN

关于以上静态属性的含义和值,详见双精度浮点数中的四类常量arrow-up-right

最后一个,Number.prototype 允许向 Number 对象添加属性。

3.3 静态方法

  1. 布尔判断

    • Number.isNaN()

    • Number.isFinite()

    • Number.isInteger()

    • Number.isSafeInteger()

  2. 类型转换

    • Number.parseFloat(string)

    • Number.parseInt(string, [radix])

3.4 实例方法

Number.prototype.xxx

3.4.1 通用方法

  1. valueOf() 返回原始值

  2. toString([radix]) 返回以指定基数表示的字符串

  3. toLocaleString([locales [, options]])

3.4.2 常用操作

  1. toPrecision(precision) 返回指定精度的数值字符串

  2. toFixed(digits) 小数点后保留固定位数(using fixed-point notation,使用定点符号)

  3. toExponential(fractionDigits) 返回以指数表示法表示的数值字符串

4. 注意事项

4.1 判断一个值是否为 NaN

NaN 是 JavaScript 中唯一不等于自身的值。

当我们想判断一个值是不是 NaN 的时候,可以使用 isNaN()Number.isNaN(),或者是进行下自我比较,因为只有 NaN 不等于自身。代码如下:

4.2 isNaN()Number.isNaN()

它两的区别在于:当一个非 NaN 的值经过强制类型转换之后值是 NaN 时,isNaN() 是返回 true,而 Number.isNaN() 是返回 false。如下:

也就是说 Number.isNaN() 只有当值是 NaN 时才会返回 true。

基于同样的原因,当参数是个 BigInt 值的时候,它两的表现也不一样。如下:

此外,数组的有些方法找不到 NaN 值,而有些方法可以。比如:

4.3 判断是否相等

对于非整数的计算结果,不能用 ===== 进行比较,正确的比较方法是检测相差的微小值。比如:

5. 主要参考

Last updated