JSON.stringify() 是核心方法,安全转换需处理循环引用、undefined/函数/Symbol(静默跳过)、特殊类型(如 Date/BigInt/RegExp)及 NaN/Infinity(转 null);推荐用 replacer 函数过滤非法值并转换特殊类型,配合 WeakMap 检测循环引用。

JavaScript 中把数组或对象转成 JSON 字符串,核心方法是 JSON.stringify(),但“安全”转换的关键在于处理好无法序列化的值、循环引用和特殊类型。
避开常见报错:哪些值不能直接 stringify
JSON.stringify() 会静默跳过 undefined、函数(function)、Symbol 类型,遇到循环引用(比如对象属性引用自身)则直接抛出 TypeError。例如:
❌ 报错示例:
const obj = { a: 1 };
obj.self = obj; // 循环引用
JSON.stringify(obj); // TypeError: Converting circular structure to JSON
✅ 安全做法:
- 提前检测循环引用(可用 WeakMap 记录已遍历对象)
- 用
replacer参数过滤掉不合法字段(如函数、undefined) - 对日期、BigInt、RegExp 等特殊类型,手动转为可序列化格式(如 ISO 字符串、数字、字符串)
用 replacer 参数控制输出内容
replacer 可以是数组(指定白名单键名)或函数(自定义每个值的处理逻辑)。推荐用函数方式做兜底清洗:
function safeReplacer(key, value) {
if (typeof value === 'function' || value === undefined || typeof value === 'symbol') {
return undefined; // 被自动忽略
}
if (value instanceof Date) return value.toISOString();
if (typeof value === 'bigint') return Number(value);
if (value instanceof RegExp) return value.toString();
return value;
}
const data = {
name: 'Alice',
birth: new Date('2000-01-01'),
id: 123n,
pattern: /abc/g,
method() { return 'no'; }
};
JSON.stringify(data, safeReplacer, 2);
// → 正常输出,无报错,特殊类型被合理转换
处理循环引用的轻量方案
不需要引入大型库时,可用一个简单缓存机制避免崩溃:
function jsonStringifySafe(obj, space) {
const seen = new WeakMap();
function replacer(key, value) {
if (typeof value === 'object' && value !== null) {
if (seen.has(value)) return '[Circular]';
seen.set(value, true);
}
return value;
}
return JSON.stringify(obj, replacer, space);
}
// 使用
jsonStringifySafe({ a: 1, b: { c: 2 } }, 2); // 正常
jsonStringifySafe({ self: {} }, 2); // 输出 { "self": "[Circular]" }
注意浏览器兼容性与边缘情况
JSON.stringify() 在所有现代浏览器和 Node.js 中都支持,但要注意:
- NaN、Infinity、-Infinity 会被转为
null(不是报错,但可能不符合预期) - 空数组
[]和空对象{}始终能安全转换 - 如果对象有
toJSON()方法,它会优先被调用 —— 这是标准行为,可主动利用来定制序列化逻辑
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











