weakset 适合标记大型对象实例,因其弱引用不阻止 gc,避免内存泄漏;而 set 的强引用易导致对象驻留内存。它仅存对象、不可迭代、无 size,适用于防重复处理等场景。

用 WeakSet 标记已处理过的大型对象实例,核心是利用它的“弱引用”特性:不阻止垃圾回收,避免内存泄漏,特别适合临时标记生命周期不确定的对象。
为什么选 WeakSet 而不是 Set?
WeakSet 只能存放对象(不能是原始值),且对所存对象是弱引用——只要该对象在别处没有强引用,即使它还在 WeakSet 中,也能被 GC 回收。而 Set 会保持强引用,容易让本该被回收的大对象一直驻留内存。
比如处理一个临时解析出的、带大量嵌套数据的响应对象,你只想“打个标”表示“这个我扫过了”,但不希望因此拖慢它的销毁。
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
典型用法:在遍历/递归中防重复处理
常见于树形结构遍历、图遍历、深克隆、序列化等场景,防止循环引用或重复计算:
- 声明一个全局或闭包内的
WeakSet实例(如const seen = new WeakSet()) - 每次要处理一个对象前,先用
seen.has(obj)检查 - 确认未处理过,就用
seen.add(obj)标记,再执行逻辑
示例(深拷贝中跳过已访问对象):
function deepClone(obj, seen = new WeakSet()) {
if (obj === null || typeof obj !== 'object') return obj;
if (seen.has(obj)) return obj; // 防循环引用
seen.add(obj);
if (Array.isArray(obj)) {
return obj.map(item => deepClone(item, seen));
}
const cloned = {};
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
cloned[key] = deepClone(obj[key], seen);
}
}
return cloned;
}
注意事项和边界情况
-
WeakSet不可迭代,不能for...of或size属性——它只提供add/has/delete,设计上就是“纯标记容器” - 不能存储
null或原始值(如42、"str"),会报错 - 如果对象仅被 WeakSet 引用,它可能在任意一次 GC 后消失——所以不要依赖 “标记后一定能查到”,只用于“有则跳过”的乐观判断
- 多个函数共用同一个 WeakSet 时需注意作用域;若需隔离上下文(如并发处理不同批次),应为每批次新建 WeakSet
替代思路对比(什么情况下不该用)
如果需要:
– 查看所有已标记对象(WeakSet 不支持)→ 改用 Map + 对象 ID(如 obj.id)或 Symbol 键
– 标记后还要反查或统计数量 → 用 Set 或 Map,但务必手动清理(例如处理完一批后 set.clear())
– 处理的是短期存在、确定无 GC 压力的小对象 → WeakSet 和 Set 差异不大,按习惯选即可










