WeakMap & WeakSet
HardWeakMap and WeakSet hold weak references to their keys (WeakMap) or values (WeakSet). A weak reference does not prevent garbage collection — when nothing else references the key object, both the key and its associated value are automatically cleaned up.
Interactive Visualization
Built-in Data Structures
"age":30
Key Points
- WeakMap keys and WeakSet values must be objects — no primitives
- Entries are automatically garbage-collected when the key object has no other references
- Not iterable — no for...of, no .keys(), no .values(), no .entries()
- No .size property — the runtime cannot know the count since entries may be GC'd at any time
- WeakMap supports only get, set, has, delete — the minimal API
- Primary use cases: private data, DOM metadata, caching without memory leaks
Code Examples
Private Data with WeakMap
const privateData = new WeakMap() class User { constructor(name, password) { privateData.set(this, { password }) this.name = name } checkPassword(attempt) { const { password } = privateData.get(this) return attempt === password } } const user = new User('Alice', 'secret123') console.log(user.name) // 'Alice' console.log(user.password) // undefined console.log(user.checkPassword('secret123')) // true
WeakMap stores private data keyed by instance. When the instance is GC'd, the private data goes with it.
DOM Metadata Without Memory Leaks
const elementData = new WeakMap() function trackElement(element) { elementData.set(element, { clickCount: 0, createdAt: Date.now(), }) } function recordClick(element) { const data = elementData.get(element) if (data) data.clickCount++ } // If element is removed from DOM and no references remain, // the WeakMap entry is automatically garbage collected
When DOM elements are removed, WeakMap entries are cleaned up automatically. A regular Map would cause a memory leak.
Memoization Cache with WeakMap
const cache = new WeakMap() function expensiveComputation(obj) { if (cache.has(obj)) return cache.get(obj) const result = Object.keys(obj).length * 100 cache.set(obj, result) return result } let data = { a: 1, b: 2, c: 3 } expensiveComputation(data) // computes expensiveComputation(data) // cached data = null // cache entry eligible for GC
WeakMap-based caches self-clean when cached objects are no longer used.
WeakSet for Object Tagging
const visited = new WeakSet() function processNode(node) { if (visited.has(node)) return visited.add(node) console.log('Processing:', node.id) } const nodeA = { id: 'A' } processNode(nodeA) // 'Processing: A' processNode(nodeA) // skipped
WeakSet is ideal for tagging objects without preventing their garbage collection.
Common Mistakes
- Trying to use primitive values as WeakMap keys — only objects are allowed
- Attempting to iterate over a WeakMap/WeakSet — they have no iteration methods
- Using WeakMap when you need to enumerate entries — use a regular Map
- Expecting .size to exist — the runtime cannot report size
Interview Tips
- Explain the GC benefit: WeakMap/WeakSet prevent memory leaks
- Know the API limitations: not iterable, no size, keys must be objects
- Give concrete use cases: private class data, DOM metadata, caching
- Compare with Map/Set: weak variants trade enumeration for automatic memory management