JSON.stringify() 把一个 JavaScript 值转换为 JSON 字符串 —— 用于放进请求体、保存到文件,或存到 localStorage。它看起来简单,但它的三个参数、对特殊值的处理,以及 toJSON 钩子,时不时就把开发者绊倒。本指南覆盖 JSON.stringify() 做的一切、其他语言里对应的做法,以及需要避开的陷阱。
JSON.stringify 做了什么
它递归地遍历一个值,产出符合规范的 JSON 字符串。默认输出是紧凑的,不带多余空白:
const user = { name: "Ada", age: 36, active: true };
JSON.stringify(user);
// '{"name":"Ada","age":36,"active":true}'因为它始终输出合法 JSON,所以你应该永远不要手写拼接 JSON 字符串 —— 用 concat 或模板字面值都不行,这是 [object Object] 错误 与 尾随逗号错误 的头号原因。
三个参数
JSON.stringify(value, replacer, space) 接收一个值,加上两个大多数开发者从不使用、但其实很强大的可选参数。
space —— 美化输出
第三个参数控制缩进。传一个数字表示空格数,或者传字符串如 '\t' 表示 Tab:
JSON.stringify(user, null, 2);
// {
// "name": "Ada",
// "age": 36,
// "active": true
// } 这就是在代码里美化 JSON 的方式 —— 见 如何格式化 JSON。省略该参数(或传 0)就得到最小化输出;见 如何最小化 JSON。
replacer —— 过滤与变换
第二个参数可以是要保留的键数组,或一个变换每个值的函数:
// 白名单:只保留这些键
JSON.stringify(user, ['name', 'active']);
// '{"name":"Ada","active":true}'
// 函数:脱敏一个字段、丢弃另一个
JSON.stringify(
{ name: "Ada", password: "secret", token: "abc" },
(key, value) => {
if (key === 'password') return '[REDACTED]';
if (key === 'token') return undefined; // 返回 undefined 会去掉该键
return value;
},
);
// '{"name":"Ada","password":"[REDACTED]"}'toJSON 钩子
如果一个值有 toJSON() 方法,JSON.stringify() 会调用它并改为序列化返回值。这就是为什么 Date 对象会自动变成 ISO 字符串:
JSON.stringify({ when: new Date('2026-05-24T00:00:00Z') });
// '{"when":"2026-05-24T00:00:00.000Z"}' ← Date.prototype.toJSON 跑了
// 自定义 toJSON 实现自定义序列化
class Money {
constructor(cents) { this.cents = cents; }
toJSON() { return (this.cents / 100).toFixed(2); }
}
JSON.stringify({ price: new Money(1999) });
// '{"price":"19.99"}'什么会被丢掉或转换
JSON 只有六种类型, 因此 JavaScript 中没有 JSON 对应物的值会被静默丢弃或强转 —— 这是往返 bug 的常见来源:
| JavaScript 值 | JSON.stringify 的结果 |
|---|---|
undefined(在对象里) | 键被省略 |
undefined(在数组里) | null |
| 函数 | 省略(对象)/ null(数组) |
Symbol | 省略 |
NaN、Infinity | null |
Date | ISO 字符串(通过 toJSON) |
BigInt | 抛出 TypeError |
关于 JSON 与 JavaScript 对象差异的完整列表,见 JSON vs JavaScript 对象。
常见陷阱
循环引用会抛错
const a = {};
a.self = a;
JSON.stringify(a);
// TypeError: Converting circular structure to JSON
// 修复:记录已见对象的 replacer,或重构数据结构不支持 BigInt
JSON.stringify({ id: 9007199254740993n });
// TypeError: Do not know how to serialize a BigInt
// 修复:先转成字符串,或加一个 replacer
JSON.stringify({ id: 9007199254740993n }, (k, v) =>
typeof v === 'bigint' ? v.toString() : v
);大整数在往返中丢精度
超过 253 的数字无法精确表示。如果你 stringify 后又去 parse 一个大整数 ID,它可能会变化。这类 ID 请存为字符串。
相邻 API:structuredClone、reviver、以及稳定 stringify
structuredClone—— 做内存深拷贝时不要用JSON.parse(JSON.stringify(x))。structuredClone原生处理Date、Map、Set、ArrayBuffer以及循环引用,而且快得多。- 传给
JSON.parse的reviver参数 与这里的replacer对称。当你需要对 JSON 不建模的类型做无损往返时,把它们成对使用 —— 例如在replacer里把Date编码为 ISO 字符串,再在reviver里复原回来。 - 稳定 stringify 库(例如
json-stable-stringify、fast-json-stable-stringify)—— 无论键的插入顺序如何,都产出相同的字符串。当输出被哈希、签名或作为文本比较时使用(正式版本见 RFC 8785 / JCS)。
其他语言中的 Stringify
# Python
import json
json.dumps({"name": "Ada"}) # 紧凑
json.dumps({"name": "Ada"}, indent=2) # 美化
json.dumps({"name": "Ada"}, separators=(',', ':')) # 最小化
// Go
import "encoding/json"
b, _ := json.Marshal(map[string]string{"name": "Ada"})
// Ruby
require 'json'
{ name: "Ada" }.to_json在你的浏览器里 Stringify JSON
需要把一个 JSON 值转义为字符串字面值 —— 用于嵌入代码、数据库列或 shell 命令?fixjson 的 JSON Stringify 工具 即时完成,且在你的浏览器里运行,数据不发往任何服务器。
常见问题
怎样用 JSON.stringify 美化输出?
传第三个参数:JSON.stringify(value, null, 2) 表示两空格缩进,或 '\t' 表示 Tab。见 如何格式化 JSON。
为什么 JSON.stringify 丢掉了一些属性?
值为 undefined、函数或 Symbol 的属性会被省略,因为 JSON 没有对应的表示方式。用 replacer 或先做转换。
怎么 stringify 含 BigInt 的值?
JSON.stringify() 遇到 BigInt 会抛错。提供一个对 bigint 值调用 .toString() 的 replacer,并在另一端有意识地把它们解析回来。
JSON.stringify 与 JSON.parse 有什么区别?
stringify 把值变成 JSON 字符串;parse 把 JSON 字符串还原为值。两者互逆。解析中的陷阱见 在 JavaScript 中处理坏掉的 JSON。
怎么 JSON.stringify 一个 Map 或 Set?
直接序列化的话,两者都会变成 "{}" —— Map 没有可枚举的自有属性,而 Set 被序列化为空对象。请先把它们转成 JSON 友好的形态(或者用 replacer):
// Map → [key, value] 对的数组(可往返)
JSON.stringify([...myMap]);
// 或者用 replacer:
JSON.stringify({ data: myMap }, (k, v) =>
v instanceof Map ? Object.fromEntries(v) :
v instanceof Set ? [...v] : v
); 回程时在 JSON.parse 的 reviver 里用 new Map(arr) / new Set(arr) 重建,因为纯 JSON 没有 Map/Set 类型。
立即试用
- JSON Stringify —— 在浏览器里把 JSON 值转义为字符串字面值
- 如何格式化 JSON —— 用
space参数美化输出 - 如何最小化 JSON —— 紧凑形态及其用途
- 什么是 JSON? —— stringify 能产出的六种类型