选浅拷贝还是深拷贝取决于数据结构和使用场景:一层基本类型用浅拷贝高效安全;嵌套对象需深拷贝防污染;含特殊类型优先用structuredclone();性能敏感时按需深拷贝或用不可变方案。

选浅拷贝还是深拷贝,关键看数据结构和使用场景——不是越“深”越好,而是够用、安全、不浪费。
看数据是否嵌套
如果对象或数组只有一层,比如 { name: 'Alice', age: 30 } 或 [1, 2, 3],所有属性值都是基本类型,那就用浅拷贝。展开运算符 {...obj}、Object.assign()、slice() 都完全够用,速度快、内存省。
一旦出现嵌套,比如 { user: { profile: { id: 1 } } } 或 [1, { x: 2 }],再用浅拷贝就危险了:改 copy.user.profile.id,原对象也会跟着变。
看你要不要改嵌套内容
有些场景只是读取或覆盖顶层字段,嵌套部分根本不碰——比如合并配置:{ ...defaultConfig, ...userConfig }。这时浅拷贝既安全又高效。
但如果你要在副本里修改深层字段(比如表单编辑嵌套地址、拖拽更新树形节点),就必须深拷贝,否则原始数据会被意外污染。
看数据里有没有特殊类型
如果对象含 Date、RegExp、undefined、函数或 Symbol,别用 JSON.parse(JSON.stringify())。它会把日期变成字符串、丢掉函数和 undefined、忽略 Symbol 键。
更稳妥的选择是:
- 现代环境优先用 structuredClone(),它支持 Date、Map、Set、ArrayBuffer 和循环引用;
- 需兼容老浏览器时,用带循环引用检测的手写递归函数。
看性能和体积是否敏感
深拷贝要遍历所有层级,大对象(如万级节点的树、大量字段的响应式数据)会明显卡顿。这时候可以考虑:
- 只深拷贝真正要改的那一小块,而不是整个大对象;
- 用不可变数据库(如 Immutable.js)或现代状态管理方案(如 Zustand 的 immer 插件),它们在内部做路径级代理,避免全量克隆。
本质上,拷贝策略不是语法问题,而是数据所有权问题:你是否允许副本和原数据共享某一层级的内存。理清这点,选择自然就清晰了。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











