类型错误:BigInt 值无法在 JSON 中序列化

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

¥The JavaScript exception "BigInt value can't be serialized in JSON" occurs when a BigInt is encountered in JSON.stringify with no custom serialization method provided.

信息

¥Message

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)

错误类型

¥Error type

TypeError

什么地方出了错?

¥What went wrong?

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

¥You are trying to serialize a BigInt value using JSON.stringify, which does not support BigInt values by default.Sometimes, JSON stringification happens implicitly in libraries, as part of data serialization. For example, sending data to the server, storing it in external storage, or transferring it between threads would all require serialization, which is often done using JSON.

有几种方法可以处理此问题:

¥There are several ways to handle this:

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

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

¥For more information on various tradeoffs, see BigInt reference.

示例

¥Examples

提供自定义序列化方法

¥Providing a custom serialization method

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

¥By default, BigInt values are not serializable in JSON:

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

假设你打算让 JSON 包含数字值,以下是一些可行的方法:

¥Assuming you intend for the JSON to contain a number value, here are a few approaches that work:

  • 在字符串化之前将 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}'
    

也可以看看