乐趣区

ES6-WeakMap

Set 有对应的 WeakSet, Map 也有 WeakMap。这一篇,我们就来学习一下 WeakMap 有写什么特性。
先来看一下WeakMap 的基本特性

1: WeakMap 是一种存储多个键值对的无序列表
2: WeakMap 的键必须是非 null 的对象类型
3: WeakMap 的键对应的值,可以是任意类型

接下来看一下 WeakMap 的接口方法:
一:WeakMap 的新建与初始化
与 Map 相同的,WeakMap 也可以通过 new WeakMap()新建和初始化:

let weakMap1 = new WeakMap();
let key1 = {};
let key2 = {};
let weakMap2 = new WeakMap([[key1, 'key1'],[key2, 'key2']]);

只是与 Map 不同,WeakMap 的 key 必须是对象,不能是原始类型。

二:WeakMap 的增删查减
WeakMap 的接口函数与 Map 基本一致,只是没有 clear() 方法:

1: set(key, value) 添加一个键值对
2: get(key) 获取 key 对应的 value
3: has(key) 判断 key 是否存在于 WeakMap
4: delete(key) 移除 key 对应的键值对

下面我们看一个用了以上所有方法的示例:

let weakMap = new WeakMap();
let key1 = {'id': 1};
let key2 = {'id': 2};

weakMap.set(key1, {'name': 'mike'});
weakMap.set(key2, {'name': 'lily'});
console.log(weakMap.get(key1)); //{name: "mike"}
console.log(weakMap.has(key1)); //true
weakMap.delete(key1);
console.log(weakMap);

最后一行代码的打印结果为:

WeakMap {{…} => {…}}
__proto__: WeakMap
[[Entries]]: Array(1)
0: {Object => Object}
key: {id: 2}
value: {name: "lily"}
length: 1

三:WeakMap 的限制

1: WeakMap 没有 size 属性
2: WeakMap 在初始化或者调用 set()的时候,key 必须为非 null 对象,不然会抛出错误
3: WeakMap 是不可枚举的,所以没有 clear(), forEach()方法,不能在 for...of 环境下使用

四:WeakMap 的使用场景
我们前面说到 WeakMap 的 key 必须要是非 null 的对象,WeakMap 存储的 key 也是对象的 弱引用,如果在此之外不存在其他强引用,JavaScript 的引擎的垃圾回收机制会自动回收这个对象。而 key 对应的 value 如果是对象的话,那依然存储的对象的强引用。

所以当你遇到一个需要用到存储键值对的场景,在 Map 和 WeakMap 之间你需要权衡的点有:

1:你是否需要用对象做 key,如果是,那么 WeakMap 是比 Map 更好的选择
2: 如果你选择的 WeakMap,你功能的实现是否不受限与 WeakMap 本身的限制(也就是我们前面说到的‘三:WeakMap 的限制’)。

以上就是 WeakMap 的基本特殊和使用方法以及场景。

退出移动版