TypeError: BigInt value can't be serialized in JSON

当在 JSON.stringify 中遇到 BigInt 值,且未提供自定义序列化方法时,会发生 JavaScript 异常“BigInt 值不能在 JSON 中序列化”。

消息

TypeError: Do not know how to serialize a BigInt (V8-based)
TypeError: BigInt value can't be serialized in JSON (Firefox)
TypeError: JSON.stringify cannot serialize BigInt. (Safari)

错误类型

TypeError

哪里出错了?

你正在尝试使用 JSON.stringify 序列化 BigInt 值,但它默认不支持 BigInt 值。有时,JSON 字符串化会在库中隐式发生,作为数据序列化的一部分。例如,将数据发送到服务器、将其存储在外部存储中或在线程之间传输都需要序列化,这通常使用 JSON 完成。

有几种处理方法

  • 如果你可以更改数据源,请避免使用 BigInt 值,并先将其转换为数字(这可能会导致大数字的精度丢失)。
  • 如果你可以更改字符串化过程,请向 JSON.stringify 传递一个替换函数,该函数将 BigInt 值转换为字符串或数字。
  • 你还可以全局提供一个 BigInt.prototype.toJSON 方法,该方法在 BigInt 值被字符串化时调用。

有关各种权衡的更多信息,请参阅 BigInt 参考

示例

提供自定义序列化方法

默认情况下,BigInt 值不能在 JSON 中序列化

js
const data = { a: 1n };
JSON.stringify(data);
// TypeError: BigInt value can't be serialized in JSON

假设你希望 JSON 包含一个数字值,以下是一些可行的方法

  • 在字符串化之前将 BigInt 转换为数字

    js
    const data = { a: 1n };
    JSON.stringify({ ...data, a: Number(data.a) });
    // '{"a":1}'
    
  • 提供一个替换函数,将 BigInt 值转换为数字或 原始 JSON 对象

    js
    const data = { a: 1n };
    JSON.stringify(data, (key, value) =>
      typeof value === "bigint" ? Number(value) : value,
    );
    // '{"a":1}'
    
    js
    const data = { a: 1n };
    JSON.stringify(data, (key, value) =>
      typeof value === "bigint" ? JSON.rawJSON(value.toString()) : value,
    );
    // '{"a":1}'
    
  • 提供一个 BigInt.prototype.toJSON 方法,该方法在 BigInt 值被字符串化时调用

    js
    BigInt.prototype.toJSON = function () {
      return Number(this);
    };
    const data = { a: 1n };
    JSON.stringify(data);
    // '{"a":1}'
    
    js
    BigInt.prototype.toJSON = function () {
      return JSON.rawJSON(this.toString());
    };
    const data = { a: 1n };
    JSON.stringify(data);
    // '{"a":1}'
    

另见