在JavaScript开发中,JSON.stringify和JSON.parse几乎每天都会用到。除了最基本的对象和字符串互转,它们还提供一些进阶能力,同时也藏着不少容易忽略的陷阱。掌握这些细节,可以让我们在处理数据序列化时更加稳妥。

JSON.stringify的进阶用法
JSON.stringify实际接收三个参数:value、replacer和space。replacer可以是一个数组或函数,用来筛选或转换要序列化的属性;space则用来控制缩进格式。
const user = {
name: '张三',
age: 28,
password: '123456',
birthday: new Date('1995-01-01')
};
// 只保留name和age
const safe = JSON.stringify(user, ['name', 'age'], 2);
console.log(safe);
// 使用函数隐藏敏感字段并格式化日期
const str = JSON.stringify(user, function(key, value) {
if (key === 'password') return undefined;
if (value instanceof Date) return value.toISOString();
return value;
}, 2);
console.log(str);
如果对象自身定义了toJSON方法,stringify会优先使用其返回值。
const obj = {
a: 1,
toJSON() {
return { a: this.a, b: 2 };
}
};
console.log(JSON.stringify(obj)); // {"a":1,"b":2}
JSON.parse的reviver参数
JSON.parse的第二个参数reviver可以在返回结果前对每个键值对进行处理,常用于把字符串还原成Date等类型。
const json = '{"name":"张三","birthday":"1995-01-01T00:00:00.000Z"}';
const data = JSON.parse(json, function(key, value) {
if (key === 'birthday') return new Date(value);
return value;
});
console.log(data.birthday instanceof Date); // true
常见陷阱与限制
被忽略的值
在序列化时,undefined、函数以及Symbol类型的属性会被直接跳过;数组中的undefined会转为null。
const demo = {
a: undefined,
b: function() {},
c: Symbol('s'),
d: [undefined, 1]
};
console.log(JSON.stringify(demo)); // {"d":[null,1]}
循环引用报错
如果对象存在循环引用,直接调用JSON.stringify会抛出错误,需要手动处理或使用replacer断开引用。
const a = {};
a.self = a;
try {
JSON.stringify(a);
} catch (e) {
console.log('循环引用报错:', e.message);
}
Date与特殊数值
Date对象会被转为ISO字符串,parse后默认是字符串而非Date。NaN和Infinity序列化后会变成null。
| 原始值 | 序列化结果 |
|---|---|
| new Date() | ISO格式字符串 |
| NaN | null |
| Infinity | null |
总结
合理使用replacer、space和reviver,可以让JSON的序列化与反序列化更贴合业务需要。在把数据存入localStorage或通过接口传输前,务必留意undefined、函数、循环引用等边界情况,必要时先做数据清洗或使用更专业的序列化库。
JSON_stringifyJSON_parseJavaScript修改时间:2026-07-26 20:06:19