Number

Baseline 已广泛支持

此特性已相当成熟,可在许多设备和浏览器版本上使用。自 ⁨2015 年 7 月⁩以来,各浏览器均已提供此特性。

Number 值表示浮点数,如 37-9.25

Number 构造函数包含用于处理数字的常量和方法。可以使用 Number() 函数将其他类型的值转换为数字。

描述

数字最常以字面量形式表示,如 2553.14159词法语法中有更详细的参考。

js
255; // two-hundred and fifty-five
255.0; // same number
255 === 255.0; // true
255 === 0xff; // true (hexadecimal notation)
255 === 0b11111111; // true (binary notation)
255 === 0.255e3; // true (decimal exponential notation)

在 JavaScript 代码中,像 37 这样的数字字面量是浮点值,而不是整数。在日常普遍使用中没有单独的整数类型。(JavaScript 还有一个 BigInt 类型,但它不是为取代日常使用的 Number 而设计的。37 仍然是一个 number,而不是一个 BigInt。)

当作为函数使用时,Number(value) 会将字符串或其他值转换为 Number 类型。如果该值无法转换,则返回 NaN

js
Number("123"); // returns the number 123
Number("123") === 123; // true

Number("unicorn"); // NaN
Number(undefined); // NaN

数字编码

JavaScript 的 Number 类型是双精度 64 位二进制格式 IEEE 754 值,类似于 Java 或 C# 中的 double。这意味着它可以表示小数值,但对于存储的数字的大小和精度有一些限制。简而言之,一个 IEEE 754 双精度数字使用 64 位来表示 3 个部分:

  • 1 位用于符号(正或负)
  • 11 位用于指数(-1022 到 1023)
  • 52 位用于尾数(表示一个 0 到 1 之间的数字)

尾数(也称为有效数)是数字中表示实际值(有效数字)的部分。指数是尾数应乘以的 2 的幂。可以把它想象成科学记数法:

Number=(1)符号(1+尾数)2指数\text{数字} = ({-1})^{\text{符号}} \cdot (1 + \text{尾数}) \cdot 2^{\text{指数}}

尾数用 52 位存储,被解释为二进制小数 1.… 后面的数字。因此,尾数的精度为 2-52(可通过 Number.EPSILON 获得),约为 15 到 17 位十进制数字;超出此精度水平的算术运算会受到舍入的影响。

一个数字可以容纳的最大值是 21023 × (2 - 2-52)(指数为 1023,尾数为二进制的 0.1111…),可通过 Number.MAX_VALUE 获得。高于此值的值将被特殊的数字常量 Infinity 所取代。

整数只能在 -253 + 1 到 253 - 1(包含)的范围内无损精度地表示(可通过 Number.MIN_SAFE_INTEGERNumber.MAX_SAFE_INTEGER 获得),因为尾数只能容纳 53 位(包括前导的 1)。

更多细节在 ECMAScript 标准中有描述。

数字强制转换

许多期望数字的内置操作会首先将其参数强制转换为数字(这在很大程度上是为什么 Number 对象的行为与数字原始值相似)。该操作可以总结如下:

  • 数字按原样返回。
  • undefined 变为 NaN
  • null 变为 0
  • true 变为 1false 变为 0
  • 字符串通过像解析数字字面量一样来转换。解析失败会得到 NaN。与实际的数字字面量相比,有一些微小的差异:
    • 前导和尾随的空白/行终止符会被忽略。
    • 前导的 0 数字不会使数字变成八进制字面量(或在严格模式下被拒绝)。
    • +- 允许出现在字符串的开头以表示其符号。(在实际代码中,它们“看起来像”是字面量的一部分,但实际上是独立的一元运算符。)但是,符号只能出现一次,并且后面不能跟有空白。
    • Infinity-Infinity 被识别为字面量。在实际代码中,它们是全局变量。
    • 空字符串或只含空白的字符串被转换为 0
    • 不允许使用数字分隔符
  • BigInts 会抛出 TypeError,以防止意外的隐式转换导致精度损失。
  • Symbols 会抛出 TypeError
  • 对象首先通过调用其 [Symbol.toPrimitive]()(以 "number" 为提示)、valueOf()toString() 方法(按此顺序)转换为原始值。然后将得到的原始值转换为数字。

在 JavaScript 中有两种方法可以实现几乎相同的效果。

  • 一元加号+x 完全按照上面解释的数字强制转换步骤来转换 x
  • Number() 函数:Number(x) 使用相同的算法转换 x,但 BigInts 不会抛出 TypeError,而是返回它们的数值,可能会有精度损失。

Number.parseFloat()Number.parseInt()Number() 类似,但只转换字符串,并且解析规则略有不同。例如,parseInt() 不识别小数点,而 parseFloat() 不识别 0x 前缀。

整数转换

某些操作需要整数,最著名的是那些处理数组/字符串索引、日期/时间组件和数字基数的操作。在执行上述数字强制转换步骤之后,结果会被截断为整数(通过丢弃小数部分)。如果数字是 ±Infinity,它将按原样返回。如果数字是 NaN-0,它将返回为 0。因此,结果总是一个整数(不是 -0)或 ±Infinity。

值得注意的是,当转换为整数时,undefinednull 都会变成 0,因为 undefined 被转换为 NaN,而 NaN 也变成了 0

定宽数字转换

JavaScript 有一些处理整数二进制编码的底层函数,最著名的是位运算符TypedArray 对象。位运算符总是将操作数转换为 32 位整数。在这些情况下,将值转换为数字后,该数字会通过首先截断小数部分,然后取整数的二进制补码编码的最低位来规范化到给定的宽度。

js
new Int32Array([1.1, 1.9, -1.1, -1.9]); // Int32Array(4) [ 1, 1, -1, -1 ]

new Int8Array([257, -257]); // Int8Array(2) [ 1, -1 ]
// 257 = 0001 0000 0001
//     =      0000 0001 (mod 2^8)
//     = 1
// -257 = 1110 1111 1111
//      =      1111 1111 (mod 2^8)
//      = -1 (as signed integer)

new Uint8Array([257, -257]); // Uint8Array(2) [ 1, 255 ]
// -257 = 1110 1111 1111
//      =      1111 1111 (mod 2^8)
//      = 255 (as unsigned integer)

构造函数

Number()

创建 Number 对象。当作为函数调用时,它返回 Number 类型的原始值。

静态属性

Number.EPSILON

两个可表示数字之间的最小间隔。

Number.MAX_SAFE_INTEGER

JavaScript 中的最大安全整数 (253 - 1)。

Number.MAX_VALUE

可表示的最大正数。

Number.MIN_SAFE_INTEGER

JavaScript 中的最小安全整数 (-(253 - 1))。

Number.MIN_VALUE

可表示的最小正数——即最接近于零的正数(但本身不是零)。

Number.NaN

特殊的“”(Not a Number)值。

Number.NEGATIVE_INFINITY

表示负无穷大的特殊值。在溢出时返回。

Number.POSITIVE_INFINITY

表示无穷大的特殊值。在溢出时返回。

静态方法

Number.isFinite()

确定传递的值是否为有限数。

Number.isInteger()

确定传递的值是否为整数。

Number.isNaN()

确定传递的值是否为 NaN

Number.isSafeInteger()

确定传递的值是否为安全整数(介于 -(253 - 1) 和 253 - 1 之间的数字)。

Number.parseFloat()

这与全局的 parseFloat() 函数相同。

Number.parseInt()

这与全局的 parseInt() 函数相同。

实例属性

这些属性定义在 Number.prototype 上,并由所有 Number 实例共享。

Number.prototype.constructor

创建实例对象的构造函数。对于 Number 实例,初始值为 Number 构造函数。

实例方法

Number.prototype.toExponential()

以指数表示法返回表示该数字的字符串。

Number.prototype.toFixed()

以定点表示法返回表示该数字的字符串。

Number.prototype.toLocaleString()

返回此数字的语言敏感表示形式的字符串。覆盖 Object.prototype.toLocaleString() 方法。

Number.prototype.toPrecision()

以定点或指数表示法返回一个表示该数字并指定了精度的字符串。

Number.prototype.toString()

以指定的基数返回表示指定对象的字符串。覆盖 Object.prototype.toString() 方法。

Number.prototype.valueOf()

返回指定对象的原始值。覆盖 Object.prototype.valueOf() 方法。

示例

使用 Number 对象为数值变量赋值

以下示例使用 Number 对象的属性为几个数值变量赋值:

js
const biggestNum = Number.MAX_VALUE;
const smallestNum = Number.MIN_VALUE;
const infiniteNum = Number.POSITIVE_INFINITY;
const negInfiniteNum = Number.NEGATIVE_INFINITY;
const notANum = Number.NaN;

Number 的整数范围

以下示例显示了可以表示为 Number 对象的最小和最大整数值。

js
const biggestInt = Number.MAX_SAFE_INTEGER; // (2**53 - 1) => 9007199254740991
const smallestInt = Number.MIN_SAFE_INTEGER; // -(2**53 - 1) => -9007199254740991

当解析已序列化为 JSON 的数据时,如果整数值超出此范围,当 JSON 解析器将其强制转换为 Number 类型时,这些值可能会损坏。

一个可能的解决方法是使用 String

更大的数字可以使用 BigInt 类型来表示。

使用 Number() 转换 Date 对象

以下示例使用 Number 作为函数将 Date 对象转换为数值:

js
const d = new Date("1995-12-17T03:24:00");
console.log(Number(d));

这将输出 819199440000

将数字字符串和 null 转换为数字

js
Number("123"); // 123
Number("123") === 123; // true
Number("12.3"); // 12.3
Number("12.00"); // 12
Number("123e-1"); // 12.3
Number(""); // 0
Number(null); // 0
Number("0x11"); // 17
Number("0b11"); // 3
Number("0o11"); // 9
Number("foo"); // NaN
Number("100a"); // NaN
Number("-Infinity"); // -Infinity

规范

规范
ECMAScript® 2026 语言规范
# sec-number-objects

浏览器兼容性

另见