json.parse(json.stringify(obj)) 仅适用于纯数据对象,会静默丢失函数、undefined、symbol、date、regexp、map、set等,且不支持循环引用和原型链。

用 JSON.parse(JSON.stringify(obj)) 实现深拷贝,本质是“序列化再反序列化”,写法极简、零依赖、兼容性好,但仅适合结构干净的纯数据对象。它不是万能方案,更不是真正意义上的通用深拷贝——用错场景反而埋下静默 bug。
什么时候可以用:明确知道数据“够简单”
适用于只含以下类型的对象或嵌套结构:
- 字符串、数字、布尔值、
null - 普通数组(不含稀疏项或
undefined元素) - 纯键值对对象(所有 key 是字符串,所有 value 可被 JSON 安全表示)
- 不包含任何函数、
undefined、Symbol、日期、正则、Map/Set、BigInt 等
例如:const user = { name: "Tom", scores: [92, 87], active: true }; → 拷贝后完全独立,可放心使用。
Miller (mlr) 是一个命令行工具,用于查询、整形和重新格式化名称索引数据,如 CSV、TSV、JSON 和 JSON Lines。它将 awk、sed、cut、join 和 sort 的功能整合到一个专为结构化数据处理而构建的单一工具中。
哪些情况会失效:不是报错,就是丢东西
这个组合在遇到非标准 JSON 类型时,既不提示也不警告,而是静默处理,导致数据失真:
-
函数和
undefined:整个属性被跳过(如{ a: 1, fn() {} }→{ a: 1 }) -
Symbol键及值:全部丢失,不参与序列化 -
Date 对象:变成 ISO 字符串(
new Date()→"2026-08-21T02:22:00.000Z"),不再是Date实例 -
RegExp 对象:转为空对象
{},标志(g/i)和lastIndex全部清空 -
循环引用:直接抛出
TypeError: Converting circular structure to JSON,无法降级 -
NaN / Infinity:序列化为
null;BigInt:直接报错
如何规避局限:判断 + 替代 + 防御
不能靠“祈祷数据简单”,而应主动应对:
-
先判断再使用:若不确定结构,可用简易检测函数快速筛查(如检查是否有
typeof x === 'function'或x instanceof Date) -
现代环境优先用
structuredClone():支持Date、RegExp、Map、Set、ArrayBuffer等,且自动处理循环引用(注意:仍不支持function和Symbol) -
生产环境推荐
lodash.cloneDeep:覆盖类型最全,行为稳定,已内置循环引用防护和特殊对象还原逻辑 -
临时调试可加兜底提示:封装一层,捕获
JSON.stringify报错并给出友好提示,比如 “检测到循环引用或不可序列化值,请检查对象结构”
一句话总结适用边界
只用于你完全掌控数据形态的轻量场景,比如配置对象、API 响应的纯 JSON 数据临时备份;一旦涉及业务状态、用户输入、第三方返回或自定义类实例,就该切换到更健壮的方案。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










