约 6 分钟读完 · 更新于 2026-10-21 · 文中每条都能在下面的配套工具里动手验证
JSON.parse(JSON.stringify) 只适合「纯数据」对象:字符串、数字、布尔、普通数组。字段里出现 Date、undefined、函数、Map 中的任何一种,结果就不对了。
跑一遍就知道,丢失全是静默发生的,控制台不报任何错。
const src = {
name: '张三',
created: new Date('2026-01-01'),
pattern: /a+b/g,
note: undefined,
say() { return this.name; },
};
const copied = JSON.parse(JSON.stringify(src));
console.log(copied);
// {
// name: '张三',
// created: '2026-01-01T00:00:00.000Z', ← Date 变字符串
// pattern: {}, ← RegExp 变空对象
// } ← note 和 say 被整个丢掉同一份输入,两种方式的输出差异一览。
| 输入值 | JSON 方式结果 | structuredClone 结果 |
|---|---|---|
| undefined 字段 | 字段被丢掉 | 原样保留 |
| new Date() | 变成 ISO 字符串 | Date 实例 |
| /a+b/g | 变成空对象 {} | RegExp 实例 |
| NaN / Infinity | 变成 null | 原样保留 |
| 循环引用 | 抛 TypeError | 正常克隆 |
| Map / Set | 变成 {} | 正常克隆 |
| 函数 | 被丢掉 | 抛 DataCloneError |
const src = {
created: new Date('2026-01-01'),
pattern: /a+b/g,
nested: { deep: [1, [2, 3]] },
tags: new Set(['a', 'b']),
};
src.self = src; // 循环引用:JSON 方式在这里直接抛错
const cloned = structuredClone(src);
console.log(cloned.created instanceof Date); // true
console.log(cloned.self === cloned); // true,循环结构完整保留这是 JSON 深拷贝最常见的报错,但报错栈通常不会指明是哪个字段引起的。
它们都只复制第一层,嵌套对象仍共享引用——改副本的嵌套字段,原对象跟着变。
const src = { name: '张三', addr: { city: '杭州' } };
const copy = { ...src };
copy.addr.city = '上海';
console.log(src.addr.city); // '上海' ← 原对象也被改了不是所有场景都需要真深拷贝,按数据形态选。
2022 年起 Chrome、Firefox、Safari、Edge 全部支持,Node 17+ 也可用,可以放心上生产。只有需要兼容 IE 时才退回手写递归或 lodash。
JSON 序列化要求结构是严格的树,循环引用会无限递归,所以直接抛 TypeError。structuredClone 基于结构化克隆算法,循环结构原样保留。
不能,函数会抛 DataCloneError,DOM 节点、Symbol 同样不支持。普通对象克隆后原型会丢失变成普通对象,自定义类实例要注意。
浅拷贝只复制第一层,嵌套的引用类型仍指向原对象;深拷贝递归复制所有层级。Object.assign 和展开运算符都是浅拷贝,嵌套对象会互相影响。