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

JavaScript 中 JSON 对象本身并不存在“属性深拷贝”这一说法——JSON 是一种数据交换格式(字符串),不是对象类型。真正需要深拷贝的是 JavaScript 对象或数组,而 JSON.stringify() + JSON.parse() 是一种常用、轻量的实现手段,前提是原始数据符合 JSON 可序列化的规范。
哪些值能被 JSON 安全深拷贝
该方法只适用于纯数据结构,即只包含以下类型的值:
- 字符串、数字、布尔值、null
- 普通对象(不含方法、不可枚举属性、原型链)
- 数组(元素也必须是上述可序列化类型)
例如:{ name: "Alice", scores: [95, 87], profile: { age: 28, city: "Shenzhen" } } —— 这类结构用 JSON.parse(JSON.stringify(obj)) 拷贝后,修改副本不会影响原对象。
哪些值会丢失或出错
一旦对象里出现以下内容,JSON 方法就会失效:
- 函数:直接被忽略,拷贝后该属性消失
-
undefined / Symbol:序列化时被跳过(
undefined不出现在结果中,Symbol被忽略) -
Date 对象:变成 ISO 字符串,如
new Date("2026-08-13") → "2026-08-13T00:00:00.000Z" -
正则表达式:反序列化后变成空对象
{} - Map / Set / ArrayBuffer / BigInt:无法序列化,报错或转为空对象
-
循环引用:如
obj.a = obj,直接抛出TypeError: Converting circular structure to JSON
替代方案推荐
根据环境和需求选择更稳妥的方式:
-
现代浏览器/新项目:优先用
structuredClone(obj),支持 Date、RegExp、Map、Set、Blob、循环引用等,且原生安全 -
兼容老环境或需定制逻辑:手写递归深拷贝,配合
Object.prototype.toString.call()判断类型,并用WeakMap处理循环引用 -
工程化项目:引入 Lodash 的
_.cloneDeep(),覆盖几乎所有边界情况,稳定可靠
记住:深拷贝的本质是切断所有层级的引用关系。JSON 方法只是利用字符串“无引用”的特性取巧实现,不是万能解法。确认数据干净再用,否则容易静默出错。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











