WeakSet 适合存储 DOM 节点因其弱引用不阻止垃圾回收,避免内存泄漏;仅接受对象、不可遍历、无 size 和 clear 方法,常与 MutationObserver 配合实现轻量生命周期感知。

WeakSet 是 JavaScript 中一种特殊的集合类型,它的核心特点是“弱引用”——它持有的对象引用不会阻止垃圾回收器(GC)回收这些对象。这使得 WeakSet 成为存储 DOM 节点引用的理想选择,尤其适用于需要临时标记、状态管理或避免内存泄漏的场景。
为什么 WeakSet 适合存 DOM 节点
DOM 节点是普通 JavaScript 对象,在被移除出文档且无其他强引用时,应能被 GC 回收。但如果用普通 Set 或数组保存它们,就会形成强引用,导致节点即使已从 DOM 中删除也无法释放内存。WeakSet 不会阻止 GC,只要节点脱离 DOM 且没有其他变量引用它,GC 就能安全清理。
注意:WeakSet 只接受对象(包括 DOM 节点),不支持原始值;且不支持遍历、size 查询或 clear 方法,这是其“弱性”的代价,也是设计初衷。
典型使用场景与写法
常见用途包括:标记已处理节点、记录正在过渡的元素、缓存计算结果但不阻碍回收。
- 创建 WeakSet 实例:const observed = new WeakSet();
- 添加节点(仅限对象):observed.add(document.getElementById('myBtn'));
- 检查是否已标记:if (observed.has(btn)) { /* 已观察 */ }
- 无需手动清理——节点被移除后,WeakSet 内部自动“失效”该条目
不能做什么?避开常见误区
WeakSet 不是万能缓存工具,需明确它的边界:
- 不能通过 WeakSet 获取所有已存节点(无法遍历)
- 不能知道当前存了多少个节点(无 size 属性)
- 不能存储字符串、数字等非对象值(weakSet.add('div') 会报错)
- 不能用于长期状态持久化——它只提供存在性检测,不保证生命周期可控
配合 MutationObserver 的实用组合
在动态 DOM 场景中,WeakSet 常与 MutationObserver 配合,实现轻量级节点生命周期感知:
- 用 WeakSet 记录“正在监听动画完成”的节点
- 节点被移除时,MutationObserver 捕获 remove 事件,但 WeakSet 已自然失效,无需手动 delete
- 动画回调中只需 if (animated.has(el)) 判断,安全又简洁

















