TypeError: BigInt 值无法在 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)

错误类型

发生了什么错误?

您正在尝试使用 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}'
    

另请参阅