今天在调用JSON.stringify方法时出现了TypeError: Do not know how to serialize a BigInt错误,先说说网上能查到的解决方案:
1.硬编码判断
if (typeof value === 'bigint') {
return value.toString();
} else if (typeof arg === 'object') {
// 如果参数是对象,使用 JSON.stringify
return JSON.stringify(arg);
}
这种对于直接序列化BigInt固然是可以的,但是当我们需要进行json序列化的情况往往是相对复杂的结构,比如一个object里面嵌套了一个BigInt类型的字段,使用上述方法进行序列化依旧会报出同样的错误。
2.覆盖BigInt的固有方法:
BigInt.prototype.toJSON = function() {
return this.toString();
};
网上还有一种覆盖BigInt已有方法的方式,预期当调用 JSON.stringify
时,遇到BigInt 对象会调用 toJSON
方法,将 BigInt 转换为字符串,然后进行序列化。这样可以避免在 JSON 序列化 BigInt 时出现的错误。然而我这里会出现编译错误!
TSError: ⨯ Unable to compile TypeScript:
test/RouteService.test.ts(139,18): error TS2339: Property 'toJSON' does not exist on type 'BigInt'.
有一种说法是:
JavaScript 不允许修改内置类型的原型方法,因此,不能在 BigInt 上直接定义
toJSON
方法来覆盖其默认行为。
如果有同学完成了此方法的定义,希望可以留言!
个人采用的是第三种办法解决的此问题:
3.定义stringify的覆盖方法:
JSON.stringify(arg)这个方法可以传递一个自定义的replacer函数,用以定义json序列化的过程
function objReplacer(key, value) {
if (typeof value === 'bigint') {
return value.toString(); // 将 BigInt 类型转换为字符串
}
return value;
}
describe('日志测试', () => {
it("BigInt To Json", async ()=>{
const bigIntObj = {
'bgi': BigInt(1000),
'ag': '2323'
}
console.log(JSON.stringify(bigIntObj,objReplacer));
})
})
打印结果如下:
{"bgi":"1000","ag":"2323"}
但是如果我们把bigIntObj定义成嵌套结构呢!比如:
const bigIntObj = { 'bgi': BigInt(1000), 'subObj':{ 'bgi2': BigInt(1001), 'ag2': '2323' }, 'ag': '2323' } 这个时候同样会报出Do not know how to serialize a BigInt的错误! 既然找到了解决问题的思路,那么这个问题必然是有解决方案的,无非就是改造replacer方法,递归处理object,完整代码如下:
function objReplacer(key, value) {
if (typeof value === 'bigint') {
return value.toString();
} else if (typeof value === 'object') {
for (const k in value) {
if (typeof value[k] === 'bigint') {
value[k] = value[k].toString();
} else if (typeof value[k] === 'object') {
value[k] = objReplacer(k, value[k]); // 递归处理嵌套对象
}
}
}
return value;
}
describe('日志测试', () => {
it("BigInt To Json", async ()=>{
const bigIntObj = {
'bgi': BigInt(1000),
'subObj':{
'bgi2': BigInt(1001),
'ag2': '2323'
},
'ag': '2323'
}
console.log(JSON.stringify(bigIntObj,objReplacer));
})
})
遇到其他类型的序列化问题,也可以按如上方式解决!