Back to JavaScript
JavaScript
medium
mid

What are WeakMap and WeakSet, and when would you use them?

Map/Set variants that hold their keys/values weakly — if nothing else references the object, it can be garbage-collected and the entry disappears. Keys must be objects; not iterable; no size. Use for: per-object private data, object-keyed caches that self-clean, and marking objects without leaking memory.

4 min read·~6 min to think through

WeakMap and WeakSet are like Map/Set but with weakly-held keys/values — which changes both their behavior and their use cases.

What "weak" means

A normal Map keeps a strong reference to its keys — as long as the Map lives, those key objects can't be garbage-collected, even if nothing else references them. Use objects as keys and forget to delete, and you've leaked memory.

A WeakMap holds keys weakly: if the WeakMap entry is the only thing referencing a key object, that object is eligible for garbage collection, and when it's collected the entry vanishes automatically. WeakSet does this for its values.

The constraints (they follow from being weak)

  • Keys/values must be objects (or non-registered symbols) — not primitives, which have no identity to weakly track.
  • Not iterable, no .size, no .clear() — because GC timing is non-deterministic, the contents aren't observably stable, so enumeration isn't allowed.
  • Minimal API — WeakMap: get/set/has/delete; WeakSet: add/has/delete.

When to use them

1. Private data tied to an object's lifetime:

js
const _private = new WeakMap();
class User {
  constructor(name) { _private.set(this, { name }); }
  getName() { return _private.get(this).name; }
}

When a User is GC'd, its private data goes too — no leak, no manual cleanup.

2. Caching / memoization keyed by object:

js
const cache = new WeakMap();
function getLayout(node) {
  if (cache.has(node)) return cache.get(node);
  const layout = expensiveMeasure(node);
  cache.set(node, layout);
  return layout;
}

A normal Map here would pin every node forever; the WeakMap lets them be collected.

3. Marking / tracking objectsWeakSet for "have I already visited/processed this object?" without keeping it alive.

4. Metadata for DOM nodes — attach data to elements; it's freed when the element is removed and GC'd.

The mental model

Use them when you want data associated with an object for exactly as long as that object lives — the GC handles cleanup for you.

The framing

"They're Map/Set whose keys/values are held weakly — if nothing else references the object, it gets garbage-collected and the entry disappears on its own, so you can't leak memory by forgetting to delete. That weakness forces the constraints: keys must be objects, and they're not iterable with no size, because GC timing is non-deterministic. I reach for them to tie data to an object's lifetime — per-instance private state, object-keyed caches that self-clean, marking objects as seen, DOM-node metadata."

Follow-up questions

  • Why can't you iterate a WeakMap or get its size?
  • Why must keys be objects?
  • How would a normal Map leak memory where a WeakMap doesn't?
  • How do you implement private fields with a WeakMap?

Common mistakes

  • Trying to use primitives as keys.
  • Expecting iteration or .size.
  • Using a regular Map for object-keyed caches and leaking memory.
  • Relying on observing exactly when entries are removed.

Performance considerations

  • Their whole point is memory: they let the GC reclaim objects and associated data instead of pinning them — preventing the slow memory growth that object-keyed regular Maps cause in long-lived apps.

Edge cases

  • Removal timing is unobservable — don't depend on it.
  • Key still referenced elsewhere — not collected.
  • Non-registered symbols now allowed as keys.

Real-world examples

  • Libraries storing private instance state in a WeakMap.
  • Self-cleaning memoization caches keyed by object; DOM-node metadata.

Senior engineer discussion

Seniors explain weak references and GC eligibility, derive the constraints from that property, and give concrete leak-avoidance use cases — private data, self-cleaning caches, object tracking.

Related questions