dfs内存消耗为o(d)(d为最大嵌套深度),仅存当前路径引用;bfs为o(n)(n为可遍历值总数),需暂存整层节点,峰值内存更高但规避栈溢出。

手动实现深拷贝时,DFS 和 BFS 的内存消耗差异主要来自它们各自依赖的数据结构和遍历路径的存储方式,而不是拷贝本身占用的空间。
深度优先(DFS)实现深拷贝的内存特点
DFS 通常用递归或显式栈实现。在深拷贝场景中,它会一路递归进入嵌套最深的属性,直到遇到基础类型才开始回退、构造新对象。
- 栈空间只保存当前路径上的引用,例如
{a: {b: {c: 1}}}最多同时存 3 层调用帧(a→b→c),空间复杂度为 O(d),d 是对象最大嵌套深度 - 不需额外记录已访问对象(除非处理循环引用),但一旦有循环,必须用 WeakMap 记录,否则栈溢出或无限递归
- 适合嵌套深、分支少的对象,比如配置树、DOM 节点链;但对宽而浅的对象(如含上百个同级属性的扁平对象),递归调用开销小,栈压力仍低
广度优先(BFS)实现深拷贝的内存特点
BFS 用队列逐层展开,先拷贝顶层所有属性,再统一处理下一层的所有值。这意味着它必须暂存大量中间节点引用。
- 队列中可能同时存下整个“当前层”的所有待处理对象/数组,例如一个含 100 个子对象的数组,第一层就要入队 100 个引用,空间复杂度接近 O(n),n 是待拷贝对象中可遍历值的总数
- 同样需要 WeakMap 防循环引用,但队列 + Map 两者叠加,实际内存占用明显高于 DFS
- 优势在于能更早发现循环引用(因逐层展开,上层对象在下层前已被记录),也更适合流式处理或中断恢复场景
关键对比:不是“谁更省”,而是“省在哪”
DFS 省的是**峰值内存**——它压栈快、出栈快,峰值只由最深路径决定;BFS 省的是**递归调用开销与栈溢出风险**,但换来了更高的常驻内存占用。真实项目中:
- 若对象嵌套不超过 10–20 层,DFS 递归版简洁安全,浏览器和 Node.js 默认栈限制通常够用
- 若对象极宽(如上千个同级 key)、且深度仅 2–3 层,BFS 队列虽占内存,但避免了千层递归,反而更稳
- 二者都必须用 WeakMap 缓存已拷贝对象来处理循环引用,这部分开销相同,不可省略
本质上,内存损耗差异源于控制流结构:栈天然压缩路径信息,队列天然摊平层级信息。选哪个,取决于你的数据形状和运行环境约束。










