浅拷贝只复制第一层引用,深拷贝递归复制所有层级;Object.assign()和展开运算符仅顶层浅拷贝,JSON.parse(JSON.stringify())最简但限制多,structuredClone()是现代推荐方案,支持更多类型且性能更优。

浅拷贝只复制第一层引用,深拷贝递归复制所有层级
浅拷贝创建一个新对象,但只复制原始对象的顶层属性值;如果某个属性是对象或数组,拷贝后两者仍指向同一内存地址。深拷贝则递归地为每个嵌套对象/数组分配新内存,确保完全独立。
常见误判是以为 Object.assign() 或展开运算符 {...obj} 能处理嵌套结构——它们只是浅拷贝,对 obj.a.b = 1 的修改会同时影响源和拷贝对象。
-
Object.assign({}, obj)和{...obj}:仅顶层浅拷贝,不处理嵌套 -
Array.prototype.slice()、Array.from(arr)、[...arr]:对数组是浅拷贝,元素为对象时仍共享引用 - 直接赋值
let b = a:连浅拷贝都不是,只是引用复制
JSON.parse(JSON.stringify()) 是最简深拷贝,但有严重限制
这是前端最常用的一行式深拷贝方案,原理是先序列化再反序列化,天然跳过引用关系。
但它无法处理:undefined、function、Symbol、BigInt、Date、RegExp、Map、Set、循环引用,且会丢失原型链和不可枚举属性。
立即学习“Java免费学习笔记(深入)”;
const obj = { a: 1, b: () => {}, c: undefined, d: new Date() };
console.log(JSON.parse(JSON.stringify(obj))); // { a: 1 } —— 其余全丢
所以它只适合「纯数据对象」(POJO),比如从 API 接收的 JSON 响应体。
structuredClone() 是现代浏览器推荐的深拷贝方案
structuredClone() 是 ES2022 引入的原生方法,能正确处理 Date、RegExp、Map、Set、ArrayBuffer、TypedArray 等,也支持循环引用,且保留可枚举属性。
但它仍不支持 function、undefined、Symbol、BigInt(会抛错),也不克隆原型链或不可枚举属性。
- 兼容性:Chrome 98+、Firefox 94+、Safari 15.4+,Node.js 17.0+(需启用
--harmony-structured-clone) - 性能优于
JSON.parse(JSON.stringify()),尤其在大数据量时 - 不能用于
window、document等宿主对象
const obj = { a: new Date(), b: new Map([['x', 1]]), c: /test/ };
const cloned = structuredClone(obj); // ✅ 正常工作
性能差异取决于数据结构深度、大小和类型
简单测试(1000 个键的扁平对象):structuredClone() 比 JSON.parse(JSON.stringify()) 快约 2–3 倍;但对含大量嵌套对象的结构,差距可能缩小甚至反转(因 structuredClone() 需做更多类型检查)。
真正拖慢性能的是深层递归 + 大量引用(如树形结构含 10k 节点),此时手写优化版(如用 WeakMap 缓存已拷贝对象避免循环)比通用方案更稳。
-
Object.assign()和展开运算符:最快,但只是浅拷贝 -
JSON.parse(JSON.stringify()):中等速度,但序列化/反序列化开销随数据体积线性增长 -
structuredClone():底层 C++ 实现,小到中等数据最快;对超大对象(>10MB)可能触发 GC 压力 - 手写递归深拷贝:可控性强,可跳过特定字段、处理特殊类型,但易出错且维护成本高
实际项目中,优先用 structuredClone();降级场景用 JSON.parse(JSON.stringify()) 并加 try/catch;涉及函数或复杂状态时,考虑是否真需要深拷贝——很多时候用不可变更新(如 immer)更合理。











