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.