Code Reference

WeakMap & WeakSet

JavaScript · Reference cheat sheet

WeakMap & WeakSet

JavaScript · Reference cheat sheet


📋 Overview

WeakMap and WeakSet hold weak references to object keys/values so entries can be garbage-collected when nothing else references the key. They are not iterable and have no .size — designed for private metadata, caching, and DOM-associated state without leaks.

🔧 Core concepts

  • WeakMap: keys must be objects (or non-registered symbols in modern engines); values any.
  • API: get, set, has, delete — no iteration.
  • WeakSet: objects only; add, has, delete.
  • GC: when key is unreachable, entry may disappear.
  • vs Map/Set: strong refs keep keys alive forever if the collection lives.
const wm = new WeakMap();
const el = document.createElement("div");
wm.set(el, { clicks: 0 });
wm.get(el).clicks++;

💡 Examples

// Private data per instance (pre-#fields pattern)
const _balance = new WeakMap();
class Account {
  constructor(amount) {
    _balance.set(this, amount);
  }
  deposit(n) {
    _balance.set(this, _balance.get(this) + n);
  }
  get balance() {
    return _balance.get(this);
  }
}

// DOM metadata without expando properties
const state = new WeakMap();
function track(el) {
  if (!state.has(el)) state.set(el, { seen: 0 });
  state.get(el).seen++;
}

// Visited set for graph walk (objects)
const seen = new WeakSet();
function walk(node) {
  if (seen.has(node)) return;
  seen.add(node);
  for (const child of node.children ?? []) walk(child);
}

// Cache expensive computation keyed by object
const cache = new WeakMap();
function meta(obj) {
  if (cache.has(obj)) return cache.get(obj);
  const value = compute(obj);
  cache.set(obj, value);
  return value;
}
// WeakRef / FinalizationRegistry (related, stronger control)
const ref = new WeakRef(obj);
ref.deref(); // obj or undefined if collected

⚠️ Pitfalls

  • Primitives cannot be WeakMap keys (except allowed symbols) — box or use Map.
  • Not enumerable: you cannot list keys for debugging easily.
  • Do not rely on when GC runs — only that entries may go away.
  • WeakMap values stay alive while the key is reachable — value holding key = leak cycle still collectable if only weakly held… avoid mutual strong cycles via other roots.
  • WeakSet has no get — membership only.

On this page