一、为什么需要BigInt?
在ES2020之前,JavaScript中只有一种数值类型——Number,它基于IEEE 754双精度浮点数标准。该标准能够精确表示的整数范围仅限于Number.MIN_SAFE_INTEGER(即-2⁵³+1)到Number.MAX_SAFE_INTEGER(即2⁵³-1)之间。一旦超过这个安全区间,整数就会发生精度丢失,例如9007199254740993会被存储为9007199254740992,从而在后续的计算或比较中产生不可预料的错误。
这种限制对于涉及金融、科学计算、加密算法、高精度时间戳或超大型ID的应用场景来说是不可接受的。开发者过去往往需要通过字符串拼接或引入第三方库来模拟大整数运算,但这样做既繁琐又容易出错。为了解决这一长期痛点,ES2020正式引入了BigInt原生类型,它可以表示任意长度的整数,彻底摆脱了Number的精度束缚。
引入BigInt后,JavaScript拥有了两种数值类型:number和bigint。两者在类型体系上严格隔离,不能相互隐式转换或混合运算,这虽然增加了一些使用门槛,但却保证了计算结果的纯粹性和可预测性。如果你需要在线测试和验证大整数运算效果,可以访问 www.ipipp.com 获取相关的演示环境。
二、如何创建BigInt?
创建一个BigInt值非常简单,最常用的方式就是在整数数字末尾直接添加字符n。例如42n就是一个bigint类型的42,而不是普通的number。这种方式直观而高效,适用于直接书写字面量大整数。
另一种方式是通过全局函数BigInt()来构造。该函数接受一个整数数值或字符串作为参数,尝试将其转换为BigInt。当传入数字时,必须确保它是严格意义上的整数,如果传入浮点数(如BigInt(3.14))或非数字字符串,都会直接抛出RangeError或SyntaxError。因此推荐优先使用字符串传递超大整数,以避开Number的精度问题。
// 方法一:在整数后面加 n
const bigInt1 = 123456789012345678901234567890n;
// 方法二:调用 BigInt() 构造函数,注意不能使用 new
const bigInt2 = BigInt("123456789012345678901234567890");
const bigInt3 = BigInt(123); // 从小整数转换,但失去bigint对超大数的支持
// 错误示例:传入小数会报错
// const bad = BigInt(1.5); // RangeError: The number 1.5 cannot be converted to a BigInt because it is not an integer
console.log(typeof bigInt2); // 'bigint'需要特别注意的是,BigInt不能使用new关键字来实例化,它不是一个构造函数,而是一个普通的函数。直接调用new BigInt()会导致TypeError。
三、BigInt的基本运算
BigInt类型支持绝大多数常规的算术运算符,包括加法+、减法-、乘法*、除法/、取模%以及幂运算**。这些运算符的表现与Number基本一致,但需注意除法运算的结果总是向零取整,不会返回小数部分,这与一些语言的整数除法行为相同。例如20n / 3n的结果是6n,而不是6.666...
除了算术运算,BigInt还支持位运算符,如按位与&、按位或|、按位异或^、左移<<、右移>>等。不过位运算操作时会把BigInt当作无限位宽的有符号整数,并且所有的位运算都需要两个操作数都是BigInt,不能混用普通数字。
const a = 20n; const b = 3n; console.log(a + b); // 23n console.log(a - b); // 17n console.log(a * b); // 60n console.log(a / b); // 6n (除法向零取整) console.log(a % b); // 2n console.log(a ** 2n); // 400n (幂运算,指数必须为BigInt) // 位运算示例 console.log(5n & 3n); // 1n console.log(5n | 3n); // 7n console.log(5n ^ 3n); // 6n console.log(5n << 1n); // 10n console.log(5n >> 1n); // 2n
此外,BigInt还可以使用一元运算符(如+、-),但正号+不能用于BigInt,因为它可能会导致与数字的隐式类型转换混淆,所以+big会抛出TypeError。负号-可以正常使用,用来获取相反数。
四、类型转换与比较
BigInt和Number分属不同的类型,它们的互相转换必须显式进行。将BigInt转换为Number可以通过全局函数Number(),但如果BigInt的值超过了Number.MAX_SAFE_INTEGER,转换后的数值就会丢失精度,变成近似值,因此需要谨慎操作。反过来,把Number转成BigInt使用BigInt()函数,同样要确保传入的是整数,否则会报错。
在比较场景中,宽松相等==会将BigInt与Number视为相等,只要它们的数学值相同,例如10n == 10结果为true。但严格相等===则不仅比较数值,还会检查类型,因此10n === 10为false。关系比较(>、<、>=、<=)可以在BigInt和Number之间直接使用,引擎会自动按照数学大小进行比较。
// 1. 比较操作 console.log(10n === 10); // false (严格相等,类型不同) console.log(10n == 10); // true (宽松相等,隐式转换后相等) console.log(10n > 5); // true (可以跨类型比较大小) console.log(10n < 20); // true // 2. 类型转换 // BigInt 转 Number (注意:大整数转换可能丢失精度) const bigNum = 123n; const num = Number(bigNum); console.log(typeof num); // 'number' // Number 转 BigInt const intNum = 456; const newBig = BigInt(intNum); console.log(typeof newBig); // 'bigint'
另外,在逻辑上下文中,BigInt可以像普通数值一样用于条件判断,0n会被视为假值,非零的BigInt都是真值。与布尔值的转换可以结合Boolean()使用。
五、使用BigInt的注意事项
尽管BigInt极大地拓展了整数的表示范围,但它也带来了一些使用上的约束。最核心的规则就是BigInt和Number绝不可以在同一个表达式中进行算术运算,简单加法10n + 1都会抛出TypeError。如果确实需要混合运算,必须通过显式转换将一边统一成同一种类型。推荐优先将数字转换为BigInt以保留精度,但如果数字本身可能包含小数,则需要开发者依据业务逻辑决定转换策略。
另一个常见的陷阱是Math对象的静态方法(如Math.max、Math.floor等)一律不能接受BigInt参数,强行传入同样会触发类型错误。这是因为这些方法内部实现都依赖Number类型。因此处理大整数时,必须自己编写判断逻辑,或者寻找支持BigInt的工具函数库。
序列化也是需要特别注意的地方。JSON.stringify默认无法处理BigInt值,会直接抛出TypeError: Do not know how to serialize a BigInt。要解决这个问题,需要自定义replacer函数,在序列化时将BigInt转换为字符串或数字(若数字安全),之后再通过JSON.parse的reviver恢复。这种做法虽然稍显繁琐,但在前后端通信中非常实用。
// 1. 不能与 Number 混合运算
// console.log(10n + 1); // TypeError: Cannot mix BigInt and other types
// 如果必须运算,需要显式转换
console.log(10n + BigInt(1)); // 11n
console.log(Number(10n) + 1); // 11
// 2. 不能使用 Math 对象的方法
// Math.max(10n, 20n); // TypeError
// 3. 无法直接序列化为 JSON
// JSON.stringify({ val: 10n }); // TypeError: Do not know how to serialize a BigInt
// 解决JSON序列化的常见做法是转为字符串
const data = { val: 10n };
const jsonString = JSON.stringify(data, (key, value) =>
typeof value === 'bigint' ? value.toString() : value
);
console.log(jsonString); // {"val":"10"}
// 解析还原时也可配合 reviver
const parsed = JSON.parse(jsonString, (key, value) => {
if (key === 'val') return BigInt(value);
return value;
});
console.log(parsed); // { val: 10n }六、总结
JavaScript的BigInt类型为开发者提供了一套内建、安全的任意精度整数处理方案,补齐了语言长久以来在高精度整型运算上的短板。无论是处理加密货币的最小单位、分布式系统中的超大ID,还是需要精确整数运算的科学计算,BigInt都能让代码变得更加简洁可靠。
使用时只要牢记它与Number的类型隔离原则,避免直接混合运算,并妥善处理JSON序列化等边缘场景,就能在项目中充分发挥BigInt的强大能力。随着现代浏览器和Node.js版本的持续更迭,如今在生产环境中使用BigInt已经没有任何后顾之忧,值得每一位JavaScript开发者掌握和运用。
JavaScript BigInt大整数运算ES2020类型转换JSON序列化修改时间:2026-08-03 10:03:35