weakset中对象为弱引用,不阻止垃圾回收,仅支持add()、has()、delete(),不可遍历和获取size,适用于临时标记、防重复处理及私有状态管理等场景。

WeakSet 中的对象是弱引用的,意味着它不会阻止垃圾回收器回收这些对象。只要对象在 WeakSet 外部没有其他强引用,即使它还在 WeakSet 里,也会被自动清除。
WeakSet 的弱引用特性
WeakSet 只能存储对象(不能存原始值),且内部对每个对象的引用是“弱”的——不计入 JavaScript 引擎的引用计数。一旦某个对象仅被 WeakSet 引用,而代码中其他地方已不再持有对该对象的引用,该对象就会被 GC 回收,WeakSet 内部也会自动清理对应条目(无需手动干预)。
- WeakSet 不支持遍历(没有 keys()、values()、entries() 等方法),也没有 size 属性,无法得知当前有多少个对象
- 只提供 add()、has()、delete() 三个方法,设计上就强调“临时存在性判断”而非长期持有
- 不能存储 null、undefined 或原始类型(如字符串、数字),否则会报错
典型应用场景:私有状态与防重复处理
WeakSet 常用于给对象打标记,又不想影响其生命周期。最常见的是模拟私有属性或避免重复初始化。
- 避免重复初始化:比如为某个 DOM 元素绑定一次事件监听器,可用 WeakSet 记录“已处理”,即使元素被移除,也不会造成内存泄漏
- 实现轻量级私有数据关联:配合闭包或模块作用域,用 WeakSet 存储“哪些对象已被赋予某类行为”,而不暴露实际数据结构
- 临时身份校验:例如在函数调用链中快速判断某个对象是否经过某道中间处理(如“是否已标准化”),且不希望因缓存导致对象无法释放
对比 Set:何时选 WeakSet?
如果需要长期持有对象、遍历内容、或确保对象一定存活,就用 Set;如果只是临时标记、关注对象是否“还活着”,并且希望完全跟随对象生命周期,WeakSet 更合适。
- Set 持有强引用 → 对象不会被 GC,适合缓存、注册表等需稳定存在的场景
- WeakSet 持有弱引用 → 对象可被 GC,适合辅助性元信息记录,无内存泄漏风险
- WeakSet 无法遍历和统计,所以不适合做“集合管理”,只适合“存在性检查”
一个实用示例:防重复装饰
假设你有一个函数,要为传入的对象添加一个不可枚举的方法,但只加一次:
const decorated = new WeakSet();function enhance(obj) {
if (!decorated.has(obj)) {
Object.defineProperty(obj, 'toString', {
value() { return '[Enhanced Object]'; },
enumerable: false
});
decorated.add(obj);
}
}
这样即使 obj 后续被丢弃,decorated 不会阻碍它回收,也不用担心 WeakSet 越积越多。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











