2020-05-16 02:55:40
JavaScript 的 JSON.stringify 和 JSON.parse 在序列化复杂对象时存在四大核心限制,可能导致数据丢失或类型错误,具体如下:
1. 无法处理循环引用使用第三方库(如 flatted)或自定义 replacer 函数过滤循环引用。
示例(使用 replacer):const getCircularReplacer = () => { const seen = new WeakSet(); return (key, value) => { if (typeof value === "object" && value !== null) { if (seen.has(value)) return "[Circular]"; seen.add(value); } return value; };};JSON.stringify(obj, getCircularReplacer()); // 输出:{"name":"test","self":"[Circular]"}
忽略:undefined、function、Symbol(对象属性被忽略,数组元素转为 null)。
转换:NaN 和 Infinity 转为 null;RegExp 变为空对象 {};Date 转为 ISO 格式字符串(但 JSON.parse 不会还原为 Date 实例)。
Map/Set 变为空对象 {}。
TypedArray(如 Uint8Array)转为普通数组,丢失类型信息。
支持循环引用、Date、RegExp、Map/Set 等,保留类型信息。
示例:const obj = { a: new Date(), b: new Map([["key", "value"]]) };const cloned = structuredClone(obj); // 完整复制
flatted:处理循环引用。
lodash.cloneDeep:深拷贝对象(支持部分特殊类型)。
对特殊对象手动转换为可序列化格式(如 Map 转为数组 [...map])。
总结:JSON.stringify 和 JSON.parse 适用于简单数据交换,但处理复杂对象时需谨慎。对于需要保留类型、原型链或循环引用的场景,建议使用 structuredClone 或专用库。