WeakMap and WeakSet
WeakMap and WeakSet
Section titled โWeakMap and WeakSetโWhat it is
Section titled โWhat it isโ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).
Before this feature
Section titled โBefore this featureโ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)After this feature
Section titled โAfter this featureโWeakMap/WeakSet allow garbage collection:
// WeakMap - keys must be objectslet user = { name: "Alice" };const metadata = new WeakMap();metadata.set(user, { lastLogin: Date.now() });
user = null; // Now can be garbage collected
// Private data patternconst 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 objectsconst visitedNodes = new WeakSet();
function traverse(node) { if (visitedNodes.has(node)) return; visitedNodes.add(node);
// Process node node.children?.forEach(traverse);}
// DOM element trackingconst clickedElements = new WeakSet();
document.querySelectorAll('button').forEach(btn => { btn.addEventListener('click', () => { clickedElements.add(btn); });});
// Cache with automatic cleanupconst cache = new WeakMap();
function processObject(obj) { if (cache.has(obj)) { return cache.get(obj); }
const result = expensiveOperation(obj); cache.set(obj, result); return result;}Why this is better
Section titled โWhy this is betterโ- 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
Key notes / edge cases
Section titled โKey notes / edge casesโ- 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 keysconst weak = new WeakMap();weak.set("key", "value"); // TypeErrorweak.set({}, "value"); // OK
// Not iterableweak.forEach(...); // TypeErrorweak.size; // undefinedfor (const [k, v] of weak) {} // TypeError
// Methods availableweak.has(obj);weak.get(obj);weak.set(obj, value);weak.delete(obj);// No clear() methodQuick practice
Section titled โQuick practiceโ-
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. -
Can you use a string as a WeakMap key?
Answer
No. WeakMap keys must be objects. Primitives (string, number, etc.) are not allowed. -
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.