Map
和 WeakMap
是两种数据结构,可用于操纵键和值之间的关系。
我们可以对 Map
的键和值使用对象或任何基本类型。
但是,WeakMap
仅接受对象(null 除外)。这意味着我们不能将基本类型用作 WeakMap
的键。
const attrs = new WeakMap()
attrs.set('color', 'plum') // error
与 Map
不同,WeakMap
不支持对键和值进行迭代。无法获取 WeakMap
的所有键或值。此外,也没有办法清除 WeakMap
。
最重要的区别是,WeakMap
不会阻止在没有对键的引用时对键进行垃圾回收。
另一方面,Map
无限期地维护对键和值的引用。一旦创建了键和值,它们将占用内存,即使没有对它们的引用,也不会被垃圾回收。这可能会导致内存泄漏问题。
考虑下面的一个简单代码,我们将一个唯一的 ID 映射到特定的人的信息:
let id = { value: 1 }
const people = new Map()
people.set(id, {
name: 'Foo',
age: 20,
address: 'Bar'
})
// 移除 id
id = null
删除键对象 id
后,它仍然能够通过映射键访问其引用:
people.keys().next().value // { value: 1 }
由于这种差异,WeakMap
(顾名思义)保存对键的弱引用。它解释了为什么它的键不可枚举,这在前面的区别中已经提到。
由于 WeakMap
保存对键的弱引用,且无法枚举,因此无法使用 keys()
、values()
、entries()
这些方法。