WeakMap & WeakSet
WeakMap and WeakSet hold weak references to their object keys/values — if there are no other references to the object, it can be garbage collected even if still in the WeakMap/WeakSet.
WeakMap is a coat check at a club — it holds your coat (metadata) while you (the object) are inside, but the moment you leave (get garbage collected), your coat vanishes too. No inventory list, no way to count coats.
WeakMap keys must be objects (or registered symbols in newer spec). Values can be anything. No iteration, no size property, no clear() — these are intentionally limited to prevent resurrecting GC'd references. Use cases: private data storage per-object without preventing GC, caching computed results keyed by object instances, tracking object state in frameworks without leaking memory. WeakSet: store a set of objects without preventing their GC — useful for tracking 'visited' objects in graph traversals without leaking.
WeakMap/WeakSet keys are 'weakly held' — they don't increment the object's reference count for GC purposes. The GC can collect the key object at any point, after which the WeakMap entry is also collected (but the timing is non-deterministic and not observable from JS). WeakRef provides a direct weak reference to an object with .deref() that returns undefined if collected. FinalizationRegistry allows registering a callback to run after an object is GC'd — useful for cleanup of external resources (e.g., unregistering native handles). In practice, WeakMap is the right tool for associating metadata with DOM nodes or objects controlled by another system.
WeakMap/WeakSet allow caching or metadata storage keyed by objects without preventing garbage collection of those objects. The classic use: a framework stores per-node metadata in a WeakMap<Node, Metadata> — when the node is removed from the DOM and dereferenced, the metadata is automatically eligible for GC. The limitation — no iteration, no size — is by design to preserve GC semantics.
WeakMap keys cannot be primitives. If you try to use a string or number as a WeakMap key, you get a TypeError. This rules out WeakMap as a general-purpose map replacement — it's specifically for object-keyed metadata patterns.