JavaScript WeakMap and WeakSet

WeakMap and WeakSet are weakly held collections designed for associating data with objects without keeping those objects alive solely because of the collection. They are useful for metadata, private state, caching, and membership tracking when entries should disappear naturally after their associated objects become unreachable.

A `WeakMap` stores key-value associations where the keys are held weakly. If an object used as a key is no longer reachable elsewhere, the presence of that key in the `WeakMap` does not by itself prevent garbage collection. A `WeakMap` is therefore useful when metadata should have the same lifetime as an object.

A `WeakSet` is similar, but it stores values for membership testing rather than key-value pairs. Its entries are weakly held, so adding an object to a `WeakSet` does not by itself keep that object alive. Typical uses include marking objects as processed or tracking membership without creating a strong reference.

Weak collections deliberately expose fewer inspection operations than `Map` and `Set`. They do not provide reliable enumeration, `size`, or iteration because garbage collection can occur at implementation-dependent times, which would make such observations nondeterministic.

Both collections use object identity for ordinary object keys or values. `WeakMap` supports operations such as `set`, `get`, `has`, and `delete`, while `WeakSet` supports `add`, `has`, and `delete`. They are especially valuable when collection entries should not determine the lifetime of the objects they reference.

Key points

Interview questions

When would you choose `WeakSet` instead of `WeakMap`?

Choose `WeakSet` when you only need to know whether an object belongs to a tracked group and do not need associated data. A common pattern is marking objects that have already been processed. `WeakSet` avoids retaining those objects solely because they were marked. If each object needs associated metadata, a `WeakMap` is the more appropriate abstraction.

What is the main difference between `Map` and `WeakMap`?

A `Map` strongly retains its keys, so a key remains reachable through the map until it is removed or the map itself becomes unreachable. A `WeakMap` does not keep eligible keys alive solely through the collection. `WeakMap` also does not support normal iteration or a `size` property. This makes it appropriate for associations whose lifetime should follow the key object.

Why can't a `WeakMap` be enumerated?

Garbage collection can remove unreachable keys at times that code cannot reliably predict. If enumeration were exposed, the result could change merely because the garbage collector happened to run. That would make collection contents nondeterministic from the program's perspective. The API therefore provides targeted operations such as `get`, `has`, and `delete` instead of enumeration.

What is a practical use for `WeakMap` in frontend code?

One use is storing metadata associated with DOM elements without adding custom properties to those elements. For example, a component system could associate internal state with an element through a `WeakMap`. When the element becomes unreachable, the association does not itself keep the element alive. This can help avoid accidental lifetime extension of objects managed by the application or browser.

Why might a `WeakMap` be preferable to adding a property directly to an object?

A `WeakMap` lets code maintain metadata externally without modifying the target object's property set. This can avoid naming collisions, accidental exposure, and changes to the object's observable structure. It also allows the metadata association to disappear when the key object becomes unreachable. The trade-off is that the metadata is accessible only through the `WeakMap`, and the collection cannot be enumerated.