如何让JSON.stringify将BigInt序列化为数字而非字符串?
问题描述
JSON.stringify不支持BigInt类型,常见的解决办法是给BigInt原型补丁toJSON方法,或者使用类似(k, v) => typeof v === 'bigint' ? v.toString() : v的替换函数,但这些方法都会把BigInt序列化为字符串而非数字类型——比如{ foo: 123n }会被序列化为{ "foo": "123" },而API需要的是{ "foo": 123 }这种数字格式的参数,且该数字可能超出JS中的最大安全整数范围。除了手动构建JSON字符串或事后去除引号外,还有其他实现方法吗?
可行方案
1. 使用专门处理BigInt的JSON库
可以用json-bigint这个库,它支持将BigInt直接序列化为JSON中的数字形式(不带引号),同时解析时能还原为BigInt,完全适配超出JS安全整数范围的数值:
// 初始化库时配置storeAsString为false,输出数字形式 const JSONbig = require('json-bigint')({ storeAsString: false }); const payload = { id: 123456789012345678901234567890n, count: 9007199254740993n }; const jsonPayload = JSONbig.stringify(payload); // 结果:{"id":123456789012345678901234567890,"count":9007199254740993}
2. 自定义递归序列化函数
如果不想依赖第三方库,可以自己实现一个递归遍历的序列化函数,直接处理BigInt类型:
function stringifyBigIntAsNumber(obj) { // 处理BigInt,直接返回数字字符串 if (typeof obj === 'bigint') { return obj.toString(); } // 处理数组,递归遍历每个元素 if (Array.isArray(obj)) { return `[${obj.map(item => stringifyBigIntAsNumber(item)).join(',')}]`; } // 处理对象,递归遍历每个键值对 if (typeof obj === 'object' && obj !== null) { const entries = Object.entries(obj).map(([key, val]) => { // 键名用标准JSON序列化,值递归处理 const serializedKey = JSON.stringify(key); const serializedVal = stringifyBigIntAsNumber(val); return `${serializedKey}:${serializedVal}`; }); return `{${entries.join(',')}}`; } // 其他类型(字符串、布尔值等)用标准JSON序列化 return JSON.stringify(obj); } // 测试示例 const testData = { bigNum: 1234567890123456789n, normalNum: 123, str: "test", nested: { huge: 9007199254740992n }, list: [1n, 2n, "abc"] }; console.log(stringifyBigIntAsNumber(testData)); // 输出:{"bigNum":1234567890123456789,"normalNum":123,"str":"test","nested":{"huge":9007199254740992},"list":[1,2,"abc"]}
这个函数会递归遍历所有嵌套的对象和数组,遇到BigInt直接输出不带引号的数字形式,其他类型保持标准JSON序列化的结果,完全避免了手动拼接或事后替换引号的问题。
内容的提问来源于stack exchange,提问作者riv
相关产品推荐
相关产品推荐

