WeakMap and WeakSet

Weak References Let the Garbage Collector Reclaim Keys When No Other Reference Exists

WeakMap and WeakSet

Learn when and why to use WeakMap and WeakSet: GC-safe object metadata caching, private data patterns, and why neither collection is iterable.

3 min read Level 2/5 #dsa#hashing#weakmap
What you'll learn
  • Explain how WeakMap holds keys by weak reference
  • Use WeakMap to cache computed metadata without memory leaks
  • State why WeakMap and WeakSet do not support iteration or size

WeakMap and WeakSet are specialised variants of Map and Set where keys (for WeakMap) or values (for WeakSet) must be objects, and those references are held weakly. A weak reference does not prevent the garbage collector from reclaiming the object; once no other strong reference to the key exists, the entry is automatically pruned.

WeakMap Basics

const cache = new WeakMap();

function processNode(node) {
  if (cache.has(node)) {
    return cache.get(node); // return cached result
  }
  const result = expensiveCompute(node);
  cache.set(node, result);
  return result;
}

function expensiveCompute(node) {
  // imagine heavy work here
  return { processed: true, id: node.id };
}

const el = { id: 1 };
console.log(processNode(el)); // computed
console.log(processNode(el)); // cached

When el falls out of scope and no other code holds a reference to it, the WeakMap entry is eligible for collection — no memory leak.

Contrast With a Regular Map

// Memory leak — Map keeps el alive forever
const strongCache = new Map();
function leakyProcess(node) {
  if (!strongCache.has(node)) {
    strongCache.set(node, { processed: true });
  }
  return strongCache.get(node);
}

// No leak — WeakMap releases the entry automatically
const weakCache = new WeakMap();
function safeProcess(node) {
  if (!weakCache.has(node)) {
    weakCache.set(node, { processed: true });
  }
  return weakCache.get(node);
}

WeakSet

WeakSet holds a set of objects weakly. A common pattern is tracking which objects have already been visited without retaining them:

const visited = new WeakSet();

function visit(obj) {
  if (visited.has(obj)) {
    console.log("already visited");
    return;
  }
  visited.add(obj);
  console.log("visiting", obj.name);
}

const page = { name: "home" };
visit(page); // "visiting home"
visit(page); // "already visited"

Why No Iteration or Size

Because the GC can remove entries at any point, exposing .size or iteration would produce non-deterministic results that differ between JS engines and even between GC cycles on the same engine. The spec deliberately omits these features to keep the semantics predictable.

FeatureMap / SetWeakMap / WeakSet
Key typeAnyObjects only
.sizeYesNo
IterableYesNo
GC-safe keysNoYes
Use caseGeneral lookupObject metadata cache

Reach for WeakMap whenever you need to attach private data or cached computations to objects that you do not own — DOM nodes, class instances from third-party libraries, request objects in a server framework.

Up Next

Now that you have the building blocks, learn the frequency-counting pattern — the most widely used hash-map technique in coding interviews.

Frequency Counting →