在 ES6 中引入了 Map 和 Set 数据结构,它们分别是 key-value 对和一组唯一的值的集合。而在 ES7 中引入了 WeakMap 和 WeakSet 数据结构,它们和 Map 和 Set 类似,也是一种键值对的集合类型,但它们的特点是对于 key 的引用是弱引用,也就是说在没有任何强引用时会被垃圾回收器回收。本文将详细介绍 WeakMap 和 WeakSet 数据结构在 JavaScript 中的使用。
WeakMap 数据结构
WeakMap 是一种只接受对象作为键名的集合类型,它类似于 Map,也是一种 key-value 的数据结构。与 Map 不同的是,WeakMap 中的 key 是弱引用关系,这意味着当 key 不再被使用时会自动被垃圾回收器回收。WeakMap 中的键名只能是对象,值可以是任意类型。WeakMap 的 API 远远不如 Map 那么丰富,只提供了以下几个方法:
构造函数
new WeakMap([iterable])
iterable:类似于 Map 的构造函数参数,是一个可迭代的二维数组或其他可迭代对象,每个元素表示一个键值对(数组,第一个元素为键,第二个元素为值)。
方法
WeakMap.prototype.get(key)
key:必须是 WeakMap 的实例中已存在的对象,获取该对象的值,如果对象不存在则返回 undefined。
WeakMap.prototype.set(key, value)
key:必须是 WeakMap 的实例中不存在的对象,即该对象不应该被保存在任何变量或其他数据结构中。value:对象key对应的值。
WeakMap.prototype.has(key)
key:判断该对象是否为 WeakMap 实例中的一个键,如果是则返回 true,否则返回 false。
WeakMap.prototype.delete(key)
key:删除 WeakMap 实例中的键值对,如果删除成功返回 true,否则返回 false。
使用示例
// www.javascriptcn.com code example
let wm = new WeakMap();
let key1 = {}, key2 = {}, key3 = {};
// 添加数据
wm.set(key1, [1, 2, 3]);
wm.set(key2, { a: 1, b: 2, c: 3 });
console.log(wm.get(key1)); // [1, 2, 3]
// 删除数据
console.log(wm.delete(key2)); // true
console.log(wm.has(key1)); // true
console.log(wm.has(key2)); // false在上面的示例中,我们创建了一个 WeakMap 实例 wm,并向其中添加了两个键值对,其中键名为空对象 key1 和 key2,值分别为数组 [1, 2, 3] 和对象 { a: 1, b: 2, c: 3 }。然后我们通过 get 方法可以获取键名为 key1 对应的值,通过 delete 方法删除键名为 key2 的键值对,通过 has 方法判断是否存在键名为 key1 的键值对。
WeakSet 数据结构
WeakSet 是一种只接受对象作为成员的集合类型,它类似于 Set,但会对成员对象建立弱引用关系,使得成员对象不再被使用时会自动被垃圾回收器回收。WeakSet 只提供了以下几个方法:
构造函数
new WeakSet([iterable])
iterable:类似于 Set 的构造函数参数,是一个可迭代的对象,成员必须是对象,重复的对象会被忽略。
方法
WeakSet.prototype.add(value)
value:必须是一个对象,将该对象加入到 WeakSet 的实例中。如果该对象已经存在,该方法不会产生任何影响。
WeakSet.prototype.has(value)
value:判断该对象是否为 WeakSet 实例中的一个成员,如果是则返回 true,否则返回 false。
WeakSet.prototype.delete(value)
value:删除 WeakSet 实例中的一个成员,如果删除成功返回 true,否则返回 false。
使用示例
// www.javascriptcn.com code example
let ws = new WeakSet();
let obj1 = {}, obj2 = {};
// 添加成员
ws.add(obj1);
console.log(ws.has(obj1)); // true
ws.delete(obj1);
console.log(ws.has(obj1)); // false在上面的示例中,我们创建了一个 WeakSet 实例 ws,并向其中添加了一个成员对象 obj1,然后通过 has 方法判断该成员对象是否在 ws 中,通过 delete 方法删除该成员对象。
注意事项
需要注意的是,由于 WeakMap 和 WeakSet 的键值只是被弱引用关系所绑定,在程序的运行过程中,如果这些键名对象的所有强引用都被移除,键值对象也会被垃圾回收器自动清除。因此在使用 WeakMap 和 WeakSet 时必须注意避免引起键名对象的内存泄漏问题。
结语
本文详细介绍了 ES7 中的 WeakMap 和 WeakSet 数据结构。与 Map 和 Set 不同的是,WeakMap 和 WeakSet 的键值都是建立弱引用关系,使得对象在不再被使用时可以自动被垃圾回收器回收,能够有效避免内存泄漏问题。在实际的开发中,可以根据具体业务场景选择使用哪种数据结构,以达到最佳的性能表现。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67cfa524e46428fe9eb5f096