weakset 是仅存储对象弱引用的集合,不阻止垃圾回收,无 size、不可迭代、不支持 clear;适用于标记活跃对象、避免内存泄漏。

WeakSet 是 JavaScript 中专为对象集合设计的弱引用容器,它不阻止垃圾回收,适合管理临时、生命周期不确定的对象引用。用对了,能避免内存泄漏;用错了,可能静默失效或报错。
WeakSet 只能存对象,且必须是强引用存在时才“有效”
WeakSet 不接受原始值(如字符串、数字、布尔),传入会直接报错。它内部只保存对对象的弱引用——这意味着:只要该对象在其他地方没有任何强引用,它就会被垃圾回收器清理,WeakSet 中对应的条目也会自动消失,无法遍历、没有 size、也不能清空。
const ws = new WeakSet();
ws.add({}); // ✅ 合法:传入一个新对象
ws.add([]); // ✅ 合法:数组也是对象
ws.add(new Date()); // ✅ 合法
ws.add("hello"); // ❌ 报错:Cannot add a non-object value to a WeakSet
典型高效使用场景:标记活跃对象,不干扰其生命周期
比如你想跟踪哪些 DOM 元素正在被某个模块处理,又不想因为自己的代码让这些元素无法被移除:
const processedElements = new WeakSet();
function handleElement(el) {
if (processedElements.has(el)) return;
// 标记为已处理
processedElements.add(el);
// 执行业务逻辑……
el.addEventListener('click', handler);
}
// 页面中某处移除了 el:el.remove()
// 此时若无其他 JS 引用 el,它会被 GC 回收,WeakSet 中的记录也自动消失
这里 WeakSet 的价值就体现出来了:你不用手动清理 processedElements,也不用担心它越积越多。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
关键操作只有三个,且都要求传入同一对象引用
-
ws.add(obj)—— 添加对象(必须是 object) -
ws.has(obj)—— 检查是否已添加(注意:{}和{}是两个不同对象,结果为 false) -
ws.delete(obj)—— 删除指定对象(同样要传原引用)
const obj = {};
ws.add(obj);
console.log(ws.has(obj)); // true
console.log(ws.has({})); // false —— 新建对象,不是同一个引用
ws.delete(obj);
console.log(ws.has(obj)); // false
不能做的事,比能做的更重要
- ❌ 不支持
ws.size(没有长度属性) - ❌ 不支持
ws.clear()(无法一键清空) - ❌ 不支持
for...of、forEach()、values()、keys()(不可迭代) - ❌ 不能通过索引访问(
ws[0]是 undefined) - ❌ 不能用扩展运算符转数组(
[...ws]会报错)
这些限制不是缺陷,而是设计使然:弱引用 + 非可遍历 = GC 友好。一旦你需要遍历、计数或持久持有,就该换用 Set。
和 Set 对比,选型看目的
| 需求 | 推荐类型 | 原因 |
|---|---|---|
| 去重数组、查存在性、做集合运算 | Set |
支持原始值、可遍历、有 size、语义清晰 |
| 标记 DOM 元素、缓存私有元数据、避免循环引用 | WeakSet |
不阻塞 GC、轻量、自动清理 |
| 给对象挂额外数据(键→值映射) | WeakMap |
键弱引用,值任意,适合私有状态 |
WeakSet 不是 Set 的“弱化版”,而是解决另一类问题的专用工具。它的高效,不在于操作快,而在于“什么都不做”——不干预内存回收,不暴露内部状态,让 JS 引擎自己决定何时清理。
本质上,WeakSet 是一种“存在性标记”,不是“数据存储”。用它时,心里要清楚:你只关心“这个对象是否被标记过”,而不关心“现在标记了几个”或“都是谁”。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










