Set深拷贝需单独处理:先用instanceof判断,新建Set后遍历原Set元素递归深拷贝并add;须用WeakMap缓存防循环引用,避免转数组导致顺序错乱或NaN重复。

Set 的深拷贝不能靠展开运算符
像 new Set([...originalSet]) 这种写法只是浅拷贝:它新建了一个 Set,但里面每个元素如果本身是对象,引用依然共享。比如原 Set 里存着一个 { id: 1 },拷贝后修改这个对象的属性,原 Set 和新 Set 都会看到变化。
递归中识别并构造新 Set
手写深拷贝函数时,遇到 Set 类型要单独分支处理:
- 先用
obj instanceof Set判断类型 - 创建空 Set:
const result = new Set() - 遍历原 Set 的每个值:
for (const item of obj) - 对每个
item递归调用深拷贝函数,再result.add(clonedItem)
注意循环引用和 WeakMap 缓存
如果 Set 里存了自身(比如 s.add(s)),或嵌套了其他已出现过的对象,必须依赖 WeakMap 记录映射关系:
- 进入函数前检查
seen.has(obj),有则直接返回缓存结果 - 新建 Set 后立即
seen.set(obj, result),避免后续重复处理 - 否则递归调用时可能无限循环,最终栈溢出
和其他内置类型保持一致逻辑
Set 的处理方式和 Map、Array、Object 是平行的:都是先构造空容器,再逐项深拷贝内容填入。不建议把 Set 转成数组再处理,那样多一层中间结构,还可能丢失原始 Set 的迭代顺序或特殊行为(如 NaN 的唯一性)。
立即学习“Java免费学习笔记(深入)”;


















