与世无争的WeakSet和WeakMap
在 JavaScript 的 ES6 版本中,引入了
WeakSet
和WeakMap
这两种新的数据结构,它们在处理对象引用和内存管理方面提供了更精细的控制。与Set
和Map
相比,WeakSet
和WeakMap
的设计有效避免了内存泄漏,特别是在处理大量对象引用时。
弱引用概念
为什么会说WeakSet和WeakMap与世无争呢?就是因为它们属于“弱引用”。在理解它们之前,我们必须先了解什么是“弱引用”:在JavaScript中,通常对象的引用是“强引用”,这意味着只要有一个引用指向某个对象,那么该对象就不会被垃圾回收机制回收,即使没有其他地方引用它。然而,“弱引用”则不同,它不会阻止对象被垃圾回收。
WeakSet是什么
简述:
WeakSet
是一种集合类型的数据结构,它只存储对象类型的值,并且这些值是弱引用的。这意味着如果一个对象除了在 WeakSet
中以外没有其他引用,那么它可能会被垃圾回收器回收,即使它仍然在 WeakSet
中。
特点:
- 成员限制:只能存储对象类型和Symbol类型���
- 弱引用:对象的引用不会阻止垃圾回收。
- 不可遍历:没有
size
属性,没有keys()
、values()
、entries()
方法,因此不能遍历其元素。 - 可用方法:
add()
,delete()
,has()
。
它并不像它老爸set那样有着丰富多彩的内置属性与方法。
举个例子:
创建一个对象并添加到set中:
let ws = new WeakSet();
let obj = {};
ws.add(obj);
console.log(ws.has(obj)); // true
obj = null; // 没有其他引用,obj 可能会被垃圾回收
WeakMap是什么
简述:
和Map结构相似,但它的键必须是对象,而值可以是任意类型。WeakMap
的键是弱引用的,这意味着如果一个对象除了作为 WeakMap
的键以外没有其他引用,那么这个键和它对应的值都会被垃圾回收。
特点:
- 键限制:键只能是对象。
- 弱引用:键的引用不会阻止垃圾回收。
- 不可遍历:没有
size
属性,没有keys()
、values()
或entries()
方法,因此不能遍历其键值对。 - 主要方法:
get()
,set()
,delete()
,has()
。
举个例子:
let wm = new WeakMap();
let keyObj = {};
wm.set(keyObj, 'Hello');
console.log(wm.get(keyObj)); // 'Hello'
keyObj = null; // 没有其他引用,keyObj 可能会被垃圾回收
使用场景
WeakSet
和 WeakMap
最常用于需要缓存对象但又不想导致内存泄漏的场景。例如,当处理大量 DOM 元素时,使用 WeakSet
来存储这些元素可以确保当它们不再被页面引用时能够被及时回收,避免内存占用过高。垃圾回收机制像个老爷爷,并没有固定的时间行动。
简而言之,它俩的作用就是在你不需要这个对象时好让垃圾回收机制清除避免不必要的内存占用,提高性能,在大型项目中便会要求使用这种机制。
转载自:https://juejin.cn/post/7388459061758263331