一、什么是 WeakMap 和 WeakSet?
简单来说,WeakMap
和 WeakSet
都是基于弱引用的数据结构。这意味着,如果一个对象只被 WeakMap
或 WeakSet
引用,而没有其他强引用指向它,那么垃圾回收器(Garbage Collector, GC)就可以回收这个对象,而 WeakMap
和 WeakSet
中对应的键值对或元素也会被自动移除。
二、核心特性:与普通Set/Map的致命差异
1. 弱引用机制
• WeakMap的键和WeakSet的值必须是对象 ,且这些对象的引用是"弱"的。
• 当对象被外部所有强引用释放后,WeakMap/WeakSet中的对应条目会被GC自动清理。
• 对比普通Map/Set:强引用会阻止GC回收,即使对象已不再使用。
2. 不可遍历性
• WeakMap和WeakSet没有size
属性,也不支持forEach
、keys
等方法。这是为了防止因遍历操作意外保留对象引用。
3. 操作限制
• 仅支持基础操作:set()
/add()
、get()
/has()
、delete()
。
三、使用场景:从理论到实战
1. WeakMap:关联数据的隐形守护者
• DOM元素元数据存储
当DOM元素被移除时,WeakMap自动清理关联数据,避免手动解除引用的麻烦。
javascript
const domData = new WeakMap();
const button = document.getElementById('btn');
domData.set(button, { clicks: 0 }); // 元素删除后,数据自动消失
• 实现私有属性
通过WeakMap模拟类的私有变量,外部无法直接访问:
javascript
const privateData = new WeakMap();
class User {
constructor(name) {
privateData.set(this, { name });
}
getName() {
return privateData.get(this).name;
}
}
• 临时缓存与自动清理
存储临时对象(如用户会话),无需担心内存泄漏。