javascript原生json不支持bigint,需用replacer将bigint转为{"$bigint":"..."}结构,再用reviver严格校验并还原;封装为bigintjson.stringify/parse可复用,注意字符串合法性验证与两端协议一致。

JavaScript 原生 JSON.stringify() 和 JSON.parse() 不支持 BigInt,直接序列化会抛错(TypeError: Do not know how to serialize a BigInt),而手动转成字符串又容易在反序列化时遗漏类型还原,导致后续计算出错。关键是要统一处理序列化和解析逻辑,确保 BigInt 被识别为数值类型而非普通字符串。
序列化时将 BigInt 转为带标识的字符串
用自定义 replacer 函数,在 JSON.stringify() 中把 BigInt 替换成形如 {"$bigint": "12345678901234567890"} 的对象结构,既保留精度,又标记类型,避免和普通数字或字符串混淆。
function bigIntReplacer(key, value) {
if (typeof value === 'bigint') {
return { '$bigint': value.toString() };
}
return value;
}
const data = { id: 1n, count: 9007199254740991123456789n };
const json = JSON.stringify(data, bigIntReplacer);
// → {"id":{"$bigint":"1"},"count":{"$bigint":"9007199254740991123456789"}}
解析时识别并还原 BigInt
用自定义 reviver 函数,在 JSON.parse() 时检查是否为 { "$bigint": "..." } 结构,是则用 BigInt() 还原。注意要严格校验字段名和值类型,防止误转换。
详细的 Three.js 3D 图形参考,涵盖场景设置、相机、几何体、材质、光照、动画、控制器、加载器、数学工具和调试。
- 只对形如
{ "$bigint": string }的对象还原,忽略其他结构 - 确保字符串内容符合 BigInt 字面量格式(可选
+、不可含小数点或空格) - 捕获
BigInt()抛出的异常,避免解析失败(例如非法字符串)
function bigIntReviver(key, value) {
if (value && typeof value === 'object' && '$bigint' in value && typeof value.$bigint === 'string') {
try {
return BigInt(value.$bigint);
} catch (e) {
// 可选择返回原对象、null 或抛出自定义错误
return value; // 保守 fallback
}
}
return value;
}
const parsed = JSON.parse(json, bigIntReviver);
// → { id: 1n, count: 9007199254740991123456789n }
封装成可复用的工具函数
把序列化和解析逻辑打包,降低使用成本,也方便统一维护边界情况(比如嵌套、数组、null/undefined 等)。
const BigIntJSON = {
stringify: (obj) => JSON.stringify(obj, (key, value) => {
if (typeof value === 'bigint') return { '$bigint': value.toString() };
return value;
}),
parse: (str) => JSON.parse(str, (key, value) => {
if (value && typeof value === 'object' && '$bigint' in value && typeof value.$bigint === 'string') {
try { return BigInt(value.$bigint); } catch { return value; }
}
return value;
})
};
// 使用示例
const jsonStr = BigIntJSON.stringify({ x: 123n, items: [456n, 789n] });
const obj = BigIntJSON.parse(jsonStr);
注意事项与替代方案
这种方案适用于大多数前后端传输或本地存储场景,但需两端约定一致。若服务端不支持该格式(如后端语言没实现对应解析器),可考虑:
- 统一用字符串字段(如
"id_str": "12345678901234567890"),业务层自行调用BigInt() - 改用 MessagePack、Protocol Buffers 等二进制格式,天然支持大整数
- 限制数据范围,确保不超过
Number.MAX_SAFE_INTEGER(仅当业务允许时)
不复杂但容易忽略细节:一定要验证字符串合法性,且不要在 reviver 中无条件调用 BigInt(),否则可能把任意对象误转。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










