json.parse(json.stringify())不是真正深拷贝,会丢失函数、undefined、symbol、date(变字符串)、regexp(变空对象)、nan/infinity(变null),且无法处理循环引用和特殊内置对象。

JavaScript 中处理 JSON 数据靠的是两个原生方法:JSON.parse() 解析字符串为对象,JSON.stringify() 把对象转成字符串。它们看起来简单,但格式稍有偏差就会出错或静默丢数据。
JSON.parse() 解析时必须注意格式
它只接受严格符合 JSON 标准的字符串,不是 JS 对象字面量。常见错误包括:
- 键名或字符串值用了单引号,比如
{"name": 'Alice'}→ 必须写成{"name": "Alice"} - 结尾多了一个逗号,比如
{"a": 1, "b": 2,}→ JSON 不允许尾逗号 - 包含
undefined、function、Symbol或注释 → 这些都不是合法 JSON 值 - 直接传入非字符串类型(如已解析的对象)→ 会报
TypeError: JSON.parse expects a string
安全做法是始终用 try-catch 包裹:
try { const data = JSON.parse(str); } catch (e) { console.error("解析失败", e.message); }JSON.stringify() 会悄悄跳过某些值
它不是“原样转字符串”,而是一套有规则的过滤过程:
-
undefined、函数、Symbol类型的属性值会被整个忽略(连键一起消失) - 循环引用的对象会直接抛出
TypeError -
Date自动转为 ISO 字符串;RegExp变成空对象{};NaN和Infinity变成null -
BigInt、Map、Set等原生不支持,需手动转换
可以用第二个参数控制输出,例如只保留特定字段:
JSON.stringify(obj, ['id', 'title'])fetch 场景下别直接 JSON.parse()
从网络请求拿到的不是字符串,而是 Response 对象。不能写 JSON.parse(await fetch(...))。
- 正确做法:先调
res.json(),它内部调用JSON.parse()并返回 Promise - 记得检查
res.ok,因为404或500响应也可能含 JSON 错误体 - 如果后端返回非标准格式(比如带单引号),需在服务端修复,前端不宜自行 replace 处理
需要深拷贝?谨慎用 JSON 方法
有人用 JSON.parse(JSON.stringify(obj)) 实现深拷贝,但它有明显缺陷:
- 丢失函数、
undefined、Date、RegExp、Map、Set、BigInt - 无法处理循环引用、
Symbol键、原型链 - 仅适用于纯数据对象(POJO)
真正需要深拷贝时,优先考虑结构克隆逻辑或专用库(如 structuredClone),而不是依赖 JSON 方法。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











