作者:本站站长
发布日期:2025年9月26日
在现代 Web 开发中,JSON.parse() 和 JSON.stringify() 是处理数据序列化和反序列化的两个核心方法。它们看似简单,但若不了解其细节,极易掉入“陷阱”。
// 示例:基础用法
const obj = { name: "张三", age: 25 };
const jsonStr = JSON.stringify(obj);
console.log(jsonStr); // '{"name":"张三","age":25}'
const parsedObj = JSON.parse(jsonStr);
console.log(parsedObj.name); // "张三"
localStorage 只能存储字符串,因此需要先用 stringify 转换对象。
// 保存用户信息
const user = { id: 1, username: "alice" };
localStorage.setItem("user", JSON.stringify(user));
// 读取用户信息
const savedUser = JSON.parse(localStorage.getItem("user"));
console.log(savedUser.username); // "alice"
发送 POST 请求时,通常需要将数据转为 JSON 字符串。
fetch('/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: "李四", email: "lisi@example.com" })
});
从 API 获取的数据是字符串,需用 parse 转为对象使用。
fetch('/api/data')
.then(res => res.text()) // 或直接 .json()
.then(text => {
const data = JSON.parse(text);
console.log(data);
});
利用 stringify + parse 实现浅层深拷贝(见下文陷阱)。
const original = { a: 1, b: { c: 2 } };
const copy = JSON.parse(JSON.stringify(original));
copy.b.c = 999;
console.log(original.b.c); // 2 → 原对象未被修改
JSON.stringify() 会自动忽略这些值。
const obj = {
name: "测试",
fn: function() {}, // ❌ 被忽略
value: undefined, // ❌ 被忽略
sym: Symbol("id") // ❌ 被忽略
};
console.log(JSON.stringify(obj));
// 输出:{"name":"测试"} → 其他字段丢失!
对象内部存在循环引用时,stringify 会抛出错误。
const obj = { name: "循环" };
obj.self = obj; // 自引用
JSON.stringify(obj);
// ❌ 报错:TypeError: Converting circular structure to JSON
circular-json,或手动清理引用。
stringify 会将 Date 转为 ISO 字符串,parse 不会自动还原为 Date。
const obj = { date: new Date() };
const str = JSON.stringify(obj);
console.log(str); // {"date":"2025-09-26T02:39:00.000Z"}
const parsed = JSON.parse(str);
console.log(parsed.date); // "2025-09-26T02:39:00.000Z" → 字符串,不是 Date!
parse 的第二个参数(reviver)手动还原:
const parsed = JSON.parse(str, (key, value) => {
if (key === 'date') return new Date(value);
return value;
});
const obj = { id: 123n };
JSON.stringify(obj);
// ❌ 报错:TypeError: Do not know how to serialize a BigInt
JSON.stringify(obj, (key, value) =>
typeof value === 'bigint' ? value.toString() : value
);
JavaScript 数字精度限制可能导致超大整数出错。
const obj = { id: 9007199254740993 }; // 超过 Number.MAX_SAFE_INTEGER
console.log(JSON.parse(JSON.stringify(obj)).id);
// 可能输出 9007199254740992 → 精度丢失!
const user = { name: "Alice", password: "123", token: "abc" };
// 过滤敏感字段
const safeStr = JSON.stringify(user, ['name']);
// 只保留 name 字段
// 或使用函数动态处理
const masked = JSON.stringify(user, (key, value) => {
if (key === 'password') return '[REDACTED]';
return value;
});
console.log(masked); // {"name":"Alice","password":"[REDACTED]","token":"abc"}
const str = '{"birth":"1990-01-01"}';
const data = JSON.parse(str, (key, value) => {
if (key === 'birth') return new Date(value);
return value;
});
console.log(data.birth.getFullYear()); // 1990 → 已是 Date 对象
| 方法 | 用途 | 注意事项 |
|---|---|---|
JSON.stringify() |
对象 → JSON 字符串 | 忽略函数/undefined/Symbol;不能处理循环引用;Date 变字符串 |
JSON.parse() |
JSON 字符串 → 对象 | 不会还原 Date;需注意 XSS 风险(仅解析可信数据) |
JSON.parse/stringify。掌握 JSON.parse() 和 JSON.stringify() 的正确用法,能让你在前后端交互、状态管理、数据持久化等场景中游刃有余。避开陷阱,写出更健壮的代码!