TypeError: Do not know how to serialize a BigInt

今天在调用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));
    })
})

遇到其他类型的序列化问题,也可以按如上方式解决!

猜你喜欢

转载自blog.csdn.net/gambool/article/details/134563431
今日推荐