什么是深拷贝
710 字
4 分钟
什么是深拷贝
1. 什么是浅拷贝?
浅拷贝只创建一个新的最外层对象,内部嵌套对象仍然与原对象共用。
例如:
const original = { taskName: "市场分析", user: { name: "Alice" }};
const copy = { ...original };此时:
original copy │ │ ├─ taskName ├─ taskName │ │ └──────┐ ┌─────┘ ↓ ↓ 同一个 user 对象修改最外层字段通常互不影响:
copy.taskName = "行业分析";
console.log(original.taskName);// "市场分析"但是修改嵌套对象会影响原对象:
copy.user.name = "Bob";
console.log(original.user.name);// "Bob"原因是 copy.user 和 original.user 指向同一份内存数据。
2. 什么是深拷贝?
深拷贝不仅复制最外层对象,还递归复制内部所有嵌套对象和数组。
const deepCopy = structuredClone(original);可以理解为:
original deepCopy │ │ └─ user 对象 A └─ user 对象 B
对象 A 和对象 B 内容相同,但彼此独立现在修改副本:
deepCopy.user.name = "Carol";
console.log(original.user.name);// 不会变成 "Carol"因此,并行任务各自拿到深拷贝后,即使修改嵌套内容,也不会直接影响原始 Context 或其他任务的副本。
3. 浅拷贝和深拷贝的区别
假设原数据是:
const context = { step: 1, data: { items: ["A", "B"] }};3.1 浅拷贝
const copy = { ...context };copy.data.items.push("C");结果可能是:
context.data.items// ["A", "B", "C"]虽然修改的是 copy,但原数据也变了,因为嵌套的 data 和 items 仍然共享。
3.2 深拷贝
const copy = structuredClone(context);copy.data.items.push("C");结果是:
context.data.items// ["A", "B"]
copy.data.items// ["A", "B", "C"]二者已经完全独立。
| 对比 | 浅拷贝 | 深拷贝 |
|---|---|---|
| 最外层对象 | 独立 | 独立 |
| 嵌套对象和数组 | 通常共享 | 独立 |
| 修改嵌套数据 | 可能影响原数据 | 不影响原数据 |
| 性能和内存开销 | 较小 | 较大 |
| 适合情况 | 数据严格只读或结构简单 | 任务确实需要修改副本 |
4. 为什么“浅拷贝 + 只读”也可以安全?
这是我们在步骤并行化里提到过的做法。虽然浅拷贝仍然共享嵌套对象,但只要所有并行任务都遵守:
可以读取,不可以修改就不会发生并发覆盖。例如:
// 安全:只读取const count = localContext.searchResults.length;
// 不安全:修改了共享的嵌套数组localContext.searchResults.push(newResult);所以常见设计是:
前序数据:不可变,只允许读取并行步骤的新结果:通过 return 单独返回调度器:等待步骤结束后统一合并这通常比给每个任务深拷贝一份大型 Context 更节省内存和时间。
总之:
前序数据是并行步骤开始前,上游已经确定的共享输入;浅拷贝只复制外壳,内部数据仍可能共享;深拷贝连内部嵌套数据也复制,因此副本之间更加独立,但成本也更高。
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
相关文章智能推荐
1
什么是前序数据
Agent介绍前序数据的基本概念
2
步骤并行化
Agent介绍如何解决 Context 并发写入与 SSE 乱序问题
3
pi-subagents
Agent记录 pi-subagents 扩展的内容与实践
4
SDD 工作流
SDD简要概括一下 sdd-riper 的工作流程
5
sdd-riper 概览
SDD介绍 sdd-riper 项目
随机文章随机推荐





