BigInt是JavaScript中处理任意精度整数的原始类型,专用于值超9007199254740991且需零误差的整数场景,如雪花ID、金融分单位累计、纳秒差值及密码学运算;必须用字符串初始化,禁止经Number中转,运算需类型一致,序列化需手动转字符串。

BigInt 是 JavaScript 中专用于安全处理任意精度整数的原始类型,它不解决浮点误差,也不替代 Number,而是精准填补“超大整数”这一关键空白——只要数值可能超过 Number.MAX_SAFE_INTEGER(9007199254740991),且必须保持整数语义,就该用 BigInt。
识别真正需要 BigInt 的场景
不是所有“看起来大”的数都需要 BigInt。关键看是否同时满足:① 是整数;② 值域可能超出 9007199254740991;③ 精度丢失会引发业务错误。
- 雪花 ID(如后端返回的
"1724859301284761600")——转成 Number 后末尾变零,ID 比较、分片计算全失效 - 金融金额以“分”为单位的大额累计(如
"12345678901234567890"分 ≈ 1234 亿元)——Number 解析直接丢掉 890 分 - 纳秒级时间戳差值(如日志中两个
1724859301284761600纳秒时间相减)——毫秒级已够用,但纳秒差需完整保留 - 密码学运算(RSA 模幂、素数验证)——中间值动辄几百位,必须零误差
初始化必须绕过 Number 解析
任何经由 Number 类型中转的初始化,都会在第一步就污染精度。字符串是唯一安全入口。
- ✅ 正确:
const id = BigInt("1724859301284761600")或const n = 123456789012345678901234567890n - ❌ 错误:
BigInt(1724859301284761600)—— 这个数字字面量先被 JS 当作 Number 解析,末尾已失真 - ? 实践建议:在 axios/fetch 响应拦截器中统一用
json-bigint(配storeAsString: true),让所有长数字字段进来就是字符串,后续按需转 BigInt
运算全程保持类型纯净
BigInt 与 Number 混合运算(5n + 3)会立即抛 TypeError,这不是缺陷,而是强制你明确数据边界。
- 所有算术操作符(
+、-、*、**、%)都要求操作数同为 BigInt,例如amount + 100n、id % 1000n - 除法
/向零截断:10n / 3n === 3n(不是 3.333…) - 比较推荐用
===:虽然5n == 5为 true,但5n === 5是 false,显式体现类型差异更安全 - 避免循环内反复调用
BigInt(str);高频常量可提前定义,如const ONE_HUNDRED = 100n
序列化与跨层传递要手动适配
BigInt 不可被原生 JSON 处理,否则 JSON.stringify({id: 123n}) 直接报错。
- 发送请求前:将字段转字符串,
order.id.toString();后端若需 JSON 数字,须约定改用字符串字段接收 - 本地存储:
localStorage.setItem("lastId", bigId.toString()) - 通用序列化函数:
JSON.stringify(obj, (k, v) => typeof v === "bigint" ? v.toString() : v) - 展示金额(元):
`${(amountInCents / 100n).toString()}.${(amountInCents % 100n).toString().padStart(2, '0')}`

















