JavaScript WeakMap
什么是 WeakMap?
WeakMap 是 JavaScript ES6 (ECMAScript 2015) 引入的一种集合类型,它提供了一种存储键值对的方式,其中键必须是对象,且对键的引用是弱引用。
弱引用
弱引用是指当对象仅被 WeakMap 引用时,它可以被垃圾回收机制回收。这与 Map 不同,Map 会保持对键的强引用,阻止垃圾回收。
WeakMap 的基本特性
WeakMap 具有以下几个重要特性:
- 键必须是对象:不能使用原始数据类型(如数字、字符串)作为键
- 弱引用:不会阻止垃圾回收机制回收作为键的对象
- 不可枚举:没有提供遍历方法(如
forEach
、keys
、values
) - 不支持 size 属性:无法获取 WeakMap 中的键值对数量
WeakMap 与 Map 的区别
让我们来看一下 WeakMap 和 Map 的主要区别:
特性 | WeakMap | Map |
---|---|---|
键类型 | 只能是对象 | 任意值 |
引用类型 | 弱引用 | 强引用 |
枚举性 | 不可枚举 | 可枚举 |
size 属性 | 不支持 | 支持 |
垃圾回收 | 键对象可被回收 | 键对象不可被回收 |
WeakMap 的基本用法
创建一个 WeakMap
// 创建一个空的 WeakMap
const wm = new WeakMap();
// 使用数组初始化 WeakMap
const key1 = {};
const key2 = {};
const wm2 = new WeakMap([
[key1, 'value1'],
[key2, 'value2']
]);
WeakMap 的方法
WeakMap 提供以下四个方法:
set(key, value)
: 设置键值对,返回 WeakMap 对象本身get(key)
: 获取指定键的值,如果键不存在则返回 undefinedhas(key)
: 检查是否存在指定的键,返回布尔值delete(key)
: 删除指定的键值对,成功返回 true,否则返回 false
让我们通过代码示例来看看这些方法的使用:
const wm = new WeakMap();
const obj = {};
// 设置键值对
wm.set(obj, 'Hello WeakMap');
// 获取值
console.log(wm.get(obj)); // 输出: "Hello WeakMap"
// 检查键是否存在
console.log(wm.has(obj)); // 输出: true
// 删除键值对
wm.delete(obj);
console.log(wm.has(obj)); // 输出: false
WeakMap 的垃圾回收机制
WeakMap 的一个核心特性是它对键的弱引用,这意味着当一个对象仅被 WeakMap 作为键引用时,JavaScript 的垃圾回收机制可以回收它。这在处理大量对象引用时特别有用。
让我们通过一个例子来说明:
let wm = new WeakMap();
// 创建一个作用域
{
let obj = {}; // 局部变量
wm.set(obj, "some data");
console.log(wm.get(obj)); // 输出: "some data"
}
// 此处 obj 已离开作用域
// 在未来某个时间点, 垃圾回收机制会回收 obj 对象
// 此时 wm 中对应的键值对也会被移除
// 由于 WeakMap 不提供枚举方法和 size 属性
// 我们无法直接验证 obj 是否已被回收
// 但我们知道当 obj 被回收后,它在 wm 中的条目也将被移除
注意
无法直接观察到 WeakMap 中的键何时被垃圾回收,因为垃圾回收是由 JavaScript 引擎在后台自动执行的。