浅拷贝快因只复制顶层,时间复杂度o(n),无递归开销;深拷贝慢因需递归遍历,复杂度至少o(n×d),且内存翻倍;选型取决于数据结构与隔离需求,非单纯性能比较。

浅拷贝快,深拷贝慢——这是最直观的结论,但关键不在“快慢”本身,而在“为什么快”和“为什么慢”,以及“快多少、慢到什么程度才影响决策”。
浅拷贝:只走一层,几乎零递归开销
浅拷贝不深入嵌套结构,只复制对象或数组的第一层属性。对基本类型(数字、字符串等),它直接复制值;对引用类型(如子对象、子数组),它只复制内存地址。这意味着时间复杂度接近 O(n)(n 是顶层元素个数),且没有函数调用栈开销。
- JavaScript 中最快方式包括扩展运算符
[...arr]、arr.slice()、Object.assign({}, obj),万级简单数组实测耗时通常在 0.1–1.5ms 区间 - Python 的
list[:]比copy.copy()快约 2 倍,也印证了“无递归即轻量”的共性 - 陷阱在于:一旦数据含嵌套对象(如
[1, {x: 2}]),修改copy[1].x会同步改原数组,这不是性能问题,而是语义错误
深拷贝:逐层遍历,开销随深度和规模陡增
深拷贝必须递归访问每一层引用类型,新建所有子对象、子数组、Map/Set/Date 等实例。它的时间复杂度至少是 O(n × d)(d 为平均嵌套深度),内存占用也成倍上升。
-
JSON.parse(JSON.stringify(obj))看似简洁,但实际性能差:在百万级嵌套对象测试中,比lodash.cloneDeep慢 3–5 倍,且不支持函数、undefined、Date、RegExp、循环引用 -
structuredClone是现代浏览器首选,支持 Map/Set/Date/RegExp/ArrayBuffer 等,性能接近原生,但不支持 function 和 undefined;Chrome 98+、Firefox 94+、Safari 15.4+ 可用 - Python 的
copy.deepcopy()在处理大量嵌套字典时,耗时可达浅拷贝的 10–100 倍,内存占用翻倍以上
选型不能只看性能,要看数据结构和隔离需求
性能差异只是表象,真正决定用哪种方式的是数据特征和使用意图:
- 纯基本类型数组(如
[1, 2, 3, 'a', true])→ 浅拷贝足够,深拷贝纯属浪费 - 含单层对象但不修改嵌套属性(如配置合并:
Object.assign({}, defaults, overrides))→ 浅拷贝安全高效 - 需完全隔离、允许任意层级修改(如 React 表单状态、图表数据快照)→ 必须深拷贝,优先选
structuredClone或lodash.cloneDeep - 存在循环引用或自定义类实例 → 手写递归易出错,应依赖成熟方案(
structuredClone能处理循环引用,cloneDeep兼容性更广)
一个真实对比场景(10 万元素数组)
假设数组内每个元素是 {id: number, meta: {ts: Date, tags: string[]}}:
- 浅拷贝(
[...arr]):约 0.8ms,但修改copy[0].meta.ts会改原数组 -
structuredClone(arr):约 12–18ms,完全独立,支持 Date 和数组嵌套 -
JSON.parse(JSON.stringify(arr)):约 45ms+,且 Date 变字符串、meta.tags仍是引用(不真正深)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











