Skip to content

WeakMap and WeakSet

WeakMap and WeakSet are collections similar to Map and Set but with weak references to their keys/values, allowing garbage collection. Introduced in ES6 (2015).

Regular Map/Set prevented garbage collection:

let obj = { data: "important" };
const map = new Map();
map.set(obj, "metadata");
obj = null; // Object still in memory (Map holds reference)

WeakMap/WeakSet allow garbage collection:

// WeakMap - keys must be objects
let user = { name: "Alice" };
const metadata = new WeakMap();
metadata.set(user, { lastLogin: Date.now() });
user = null; // Now can be garbage collected
// Private data pattern
const privateData = new WeakMap();
class User {
constructor(name) {
privateData.set(this, { password: "secret" });
this.name = name;
}
checkPassword(pwd) {
return privateData.get(this).password === pwd;
}
}
// WeakSet - values must be objects
const visitedNodes = new WeakSet();
function traverse(node) {
if (visitedNodes.has(node)) return;
visitedNodes.add(node);
// Process node
node.children?.forEach(traverse);
}
// DOM element tracking
const clickedElements = new WeakSet();
document.querySelectorAll('button').forEach(btn => {
btn.addEventListener('click', () => {
clickedElements.add(btn);
});
});
// Cache with automatic cleanup
const cache = new WeakMap();
function processObject(obj) {
if (cache.has(obj)) {
return cache.get(obj);
}
const result = expensiveOperation(obj);
cache.set(obj, result);
return result;
}
  • Garbage collection: References donโ€™t prevent cleanup
  • Memory leaks: Prevents common memory leak patterns
  • Private data: Store private object data
  • Caching: Automatic cache invalidation
  • DOM nodes: Safe to reference without leaks
  • Keys/values must be objects (not primitives)
  • Not iterable (no forEach, no size property)
  • Canโ€™t clear all entries
  • No way to list all keys
  • Use for metadata or private data
// Only object keys
const weak = new WeakMap();
weak.set("key", "value"); // TypeError
weak.set({}, "value"); // OK
// Not iterable
weak.forEach(...); // TypeError
weak.size; // undefined
for (const [k, v] of weak) {} // TypeError
// Methods available
weak.has(obj);
weak.get(obj);
weak.set(obj, value);
weak.delete(obj);
// No clear() method
  1. When would you use WeakMap instead of Map?

    Answer When you want keys to be garbage collected when no longer referenced elsewhere, like caching, private data, or DOM node metadata.
  2. Can you use a string as a WeakMap key?

    Answer No. WeakMap keys must be objects. Primitives (string, number, etc.) are not allowed.
  3. Why canโ€™t you iterate over a WeakMap?

    Answer Because entries can be garbage collected at any time, making iteration unpredictable. The weak references mean you can't know what's currently in the collection.