Skip to content

JavaScript 数字

JavaScript 对数字只有一种主要类型。数字可以带或不带小数。

此外,ES2020 引入了 BigInt 用于任意精度整数。

标准的 JavaScript 数字可以是整数或浮点数值:

const pi = 3.14; // A number with decimals
const count = 100; // A number without decimals

可以使用科学(指数)计数法书写极大或极小的数字:

const largeNumber = 1.23e7; // 12,300,000
const smallNumber = 1.23e-4; // 0.000123

与许多其他编程语言不同,JavaScript 的主要数字类型没有定义不同的数字类型(例如,integer, short, long, float)。

JavaScript 数字始终存储为双精度浮点数,遵循国际 IEEE 754 标准。这种格式在 64 位中存储数字:

Fraction (Mantissa)ExponentSign
52 bits (0 - 51)11 bits (52 - 62)1 bit (63)

整数(不带小数点或指数计数法的数字)被认为是精确到 15 位数字。

const x = 999999999999999; // x will be 999999999999999
const y = 9999999999999999; // y will be 10000000000000000 (loses precision)

由于二进制表示,浮点运算并非总是 100% 精确:

const z = 0.2 + 0.1; // z might be 0.30000000000000004

要处理金融计算或需要高精度小数的场景,可以考虑使用为小数算术设计的库或对数字进行缩放(例如,使用分而非元)。

对于超出安全整数限制 (Number.MAX_SAFE_INTEGER) 的非常大的整数,请使用 BigInt。

JavaScript 支持几种数字进制:

  • 十进制 (base 10): 默认(例如,123)。
  • 十六进制 (base 16): 前缀为 0x(例如,const hex = 0xFF; // 255)。
  • 二进制 (base 2): 前缀为 0b (ES6+)(例如,const bin = 0b1010; // 10)。
  • 八进制 (base 8): 前缀为 0o (ES6+)(例如,const oct = 0o17; // 15)。
注意:旧式的八进制字面量(以零开头,如 07)在严格模式下已弃用,应避免使用。对于八进制数字,请使用 0o 前缀。

toString() 方法可以将数字转换为指定进制的字符串:

const myNumber = 128;
console.log(myNumber.toString(16)); // "80" (hexadecimal)
console.log(myNumber.toString(8)); // "200" (octal)
console.log(myNumber.toString(2)); // "10000000" (binary)

Infinity 是一个特殊的数值,代表正无穷。-Infinity 代表负无穷。这些值是由除以零或计算结果超出最大可表示数字等操作产生的。

const positiveInf = 2 / 0; // Infinity
const negativeInf = -2 / 0; // -Infinity
console.log(typeof Infinity); // "number"

NaN 是一个特殊的数值,代表一个无效或无法表示的数字。它通常是由非数字值上的算术运算或未定义的操作(例如,0/0)产生的。

const result1 = 100 / "Apple"; // NaN
const result2 = Math.sqrt(-1); // NaN

要检查一个值是否是 NaN,请使用 Number.isNaN()(推荐)或全局的 isNaN()。

  • Number.isNaN(value): 只有当 value 是 NaN 时才返回 true。它不会强制转换参数。
  • isNaN(value): 首先将参数强制转换为数字。isNaN("hello") 是 true。
const val = 100 / "Apple";
console.log(Number.isNaN(val)); // true
console.log(isNaN(val)); // true
console.log(Number.isNaN("test")); // false
console.log(isNaN("test")); // true (because "test" coerces to NaN)

任何涉及 NaN 的算术运算都会导致 NaN。typeof NaN 是 "number"。

BigInt 是 JavaScript 中较新的数值类型,可以表示任意精度的整数。这对于大于 Number.MAX_SAFE_INTEGER 的数字非常有用。

通过在整数文字后附加 n 或调用 BigInt() 函数来创建 BigInt。

const veryLargeNumber = 9007199254740991n; // Max safe integer
const evenLarger = veryLargeNumber + 1n; // 9007199254740992n
const alsoLarge = BigInt("9007199254740993");
console.log(typeof evenLarger); // "bigint"

注意:BigInt 不能直接与常规数字进行算术运算;需要显式转换。它们也不能与 Math 对象的 메서드(方法)一起使用。

JavaScript 数字通常是原始值。然而,数字也可以使用 new Number() 定义为对象。

const x = 123; // Primitive number
const y = new Number(123); // Number object
console.log(typeof x); // "number"
console.log(typeof y); // "object"
强烈建议避免使用 new Number() 创建 Number 对象。它会降低执行速度,导致等值检查 (===) 出现令人困惑的行为,并且相对于原始数字没有任何实际好处。

原始数字本身没有属性或方法。然而,JavaScript 提供了一个 Number 对象包装器,允许原始数字访问内置属性和方法。

静态属性(在 Number 本身访问):

  • Number.MAX_VALUE: 最大可表示正数。
  • Number.MIN_VALUE: 最小可表示正数(最接近零)。
  • Number.MAX_SAFE_INTEGER: 最大安全整数 (2^53 - 1)。
  • Number.MIN_SAFE_INTEGER: 最小安全整数 (-(2^53 - 1))。
  • Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY
  • Number.NaN

实例方法(在数字变量或文字上调用):

  • num.toString(base): 将数字转换为字符串(可选进制)。
  • num.toFixed(digits): 格式化为固定小数位数。
  • num.toPrecision(precision): 格式化为指定长度。
  • num.toExponential(fractionDigits): 返回指数计数法字符串。

用于数字转换/检查的全局函数:

  • parseInt(string, radix): 将字符串解析为整数。
  • parseFloat(string): 将字符串解析为浮点数。
  • isFinite(value): 检查值是否为有限数字。
  • Number.isInteger(value): 检查值是否为整数。
const maxVal = Number.MAX_VALUE;
console.log(maxVal);
const num = 123.456;
console.log(num.toFixed(2)); // "123.46"
console.log(num.toPrecision(4)); // "123.5"

有关完整列表和详细信息,请参考 MDN Web Docs 中关于 Number 对象的文档。