WeakMaps are similar to Maps, with the following differences:
- They can be used to attach data to objects, without preventing those objects from being garbage-collected.
- They are black boxes where a value can only be accessed if you have both the WeakMap and the key.
The next two sections examine in more detail what that means.
This is how you attach a value to an object via a WeakMap:
31.1.1. The keys of a WeakMap are weakly held
The keys of a WeakMap are said to be weakly held: Normally, references to an object prevent the object from being garbage-collected. However, WeakMap keys don’t. Additionally, WeakMap entries, whose keys were garbage-collected, are also (eventually) garbage-collected.
Weakly held keys only make sense for objects. Thus, you can only use objects as keys:
It is impossible to inspect what’s inside a WeakMap:
- For example, you can’t iterate or loop over keys, values or entries. And you can’t compute the size.
- Additionally, you can’t clear a WeakMap, either – you have to create a fresh instance.
These restrictions enable a security property. Quoting Mark Miller: “The mapping from weakmap/key pair value can only be observed or affected by someone who has both the weakmap and the key. Withclear()
, someone with only the WeakMap would’ve been able to affect the WeakMap-and-key-to-value mapping.”
31.3.1. Caching computed results via WeakMaps
If we use this function with an object obj
, you can see that the result is only computed for the first invocation, while a cached value is used for the second invocation:
31.3.2. Keeping private data via WeakMaps
In the following code, the WeakMaps _counter
and _action
are used to store the data of virtual properties of instances of Countdown
:
The constructor and the four methods of WeakMap
work the same as :
new WeakMap<K, V>(entries?: Iterable<[K, V]>)
[ES6].delete(key: K) : boolean
[ES6].get(key: K) : V
[ES6]- [ES6]
.set(key: K, value: V) : this
[ES6]