WeakMap
weakmap是一种类似map的类型,但它的key是弱引用,并且key只能是对象。
weakmap和map的区别
- weakmap的key只能是对象,value可以是任何值
const weakMap = new WeakMap(); // 创建WeakMap实例
const key1 = "key1"; // 字符串键
const key2 = 123; // 数字键
const key3 = { name: "John" }; // 对象键
// 尝试用非对象键会抛出TypeError
weakMap.set(key1, "value1"); // TypeError: Invalid value
weakMap.set(key2, "value2"); // TypeError: Invalid value
// 合法操作:使用对象作为键
weakMap.set(key3, "value3");
console.log(weakMap.get(key3)); // 输出:"value3"
- weakmap中的key是弱引用,不会阻止与之关联的对象被垃圾回收。而map的key是强引用。 (也就是说weakmap中对key对象的引用不会被计入到“引用计数法”垃圾清除机制的计数中)
let weakMap = new WeakMap();
let key1 = { name: "John" };
key1 = null; // 解除对象引用
// WeakMap键必须保持对象引用
weakMap.set(key1, "value1"); // 此时key1=null会报错,因为key1已经被回收
上述代码中,本来{name:“John”}对象有2个引用(key1和weakmap),但由于weakmap是弱引用,所以不计入标记清除法的计数过程中。所以一旦将key1释放,xdy已经没有任何元素引用{name:“John”}对象了。weakmap中对应的key也就随之释放。
如果换成map,那么只要map存在,{name:“John”}对象的引用数就至少为1,永远不会被释放。
3. weakmap不能通过forEach或map.keys()来遍历其中的所有key
weakmap的应用场景
- 引用DOM元素
比如记录点击按钮的次数,将weakmap的key设置为btn(指向按钮dom元素的地址),value设置为count(点击的次数)。
为什么用map不行?
如果用map,那么有朝一日我们不需要统计按钮点击次数了,就会将btn指向null。但此时这个按钮的对象并不会被移除,因为map的key依然指向它,只要map存在,它就不会被移除,那么就造成了内存泄漏! - 做缓存
同样的道理,不用map是因为如果有一天我们不需要对某个数据进行缓存了,我们希望在weakmap中存储的键值对也随着垃圾清除机制被清除。