WeakMap vs WeakSet: What Is the Difference?
Understand WeakMap vs WeakSet in JavaScript — weak references, garbage collection, and when to use each, with code examples.
Expected Interview Answer
A WeakMap stores key-value pairs where the keys must be objects held only weakly, so entries are automatically garbage-collected once nothing else references the key, while a WeakSet stores a collection of unique objects held the same weakly, with no values attached and no iteration support.
Both structures exist to avoid memory leaks when you need to associate metadata with an object without preventing that object from being garbage collected. A WeakMap is useful for attaching private data or caches to objects — for example mapping a DOM node to its event handler state — because once the DOM node is removed and has no other references, the WeakMap entry disappears too. A WeakSet is useful for tracking membership, such as marking which objects have already been processed, again without keeping them alive artificially. Neither structure is enumerable: there is no size property, no keys/values/entries iterator, and no forEach, because the garbage collector could remove entries at any nondeterministic moment, which would make iteration order unreliable. This is a deliberate tradeoff — you give up inspection and iteration in exchange for automatic, leak-free cleanup tied to object lifetime.
- Prevents memory leaks by letting garbage-collected keys/values drop automatically
- Ideal for attaching private or auxiliary data to objects without extending their lifetime
- WeakSet efficiently tracks object membership without retaining references
- Both avoid manual cleanup logic that a regular Map/Set would otherwise require
AI Mentor Explanation
A WeakMap is like a scorer attaching a private note card to a specific bat currently in use, but once that bat is retired and thrown out of the kit bag entirely, the note card is discarded automatically too. A WeakSet is like a checklist marking which bats have already been inspected this match, again tied to the bat existing in the kit at all. Neither the note card nor the checklist entry can be listed out or counted directly, because they vanish the moment the bat itself is gone. That automatic, non-enumerable cleanup tied to the referenced object is the core mechanism of both.
Step-by-Step Explanation
Step 1
Create the structure
Instantiate `new WeakMap()` or `new WeakSet()` to hold object-only references.
Step 2
Associate data with an object
For WeakMap, `set(obj, value)`; for WeakSet, `add(obj)` — keys/members must be objects, never primitives.
Step 3
Object becomes unreachable elsewhere
Once no other strong reference to that object exists, it becomes eligible for garbage collection.
Step 4
Entry is reclaimed automatically
The garbage collector removes the object and its associated WeakMap/WeakSet entry together, with no manual cleanup code.
What Interviewer Expects
- Clear distinction: WeakMap holds key-value pairs, WeakSet holds only unique object members
- Understanding that keys/members must be objects, never primitives
- Awareness that neither is enumerable (no size, no iteration, no forEach)
- A concrete use case: private object metadata or DOM node tracking without leaks
Common Mistakes
- Trying to use a primitive value as a WeakMap key or WeakSet member (throws a TypeError)
- Expecting to iterate or get the size of a WeakMap/WeakSet
- Using a WeakMap when a regular Map with manual cleanup would actually be clearer
- Assuming WeakMap values are also held weakly — only the keys are weak references
Best Answer (HR Friendly)
“WeakMap and WeakSet let you attach extra information to objects without accidentally keeping those objects alive forever in memory. WeakMap pairs a key object with a value, while WeakSet just tracks a group of unique objects, and both clean themselves up automatically once the original object is no longer used anywhere else.”
Code Example
const privateData = new WeakMap()
const processed = new WeakSet()
function attachMetadata(el, meta) {
privateData.set(el, meta) // tied to el’s lifetime
}
function markProcessed(el) {
processed.add(el)
}
let node = document.createElement('div')
attachMetadata(node, { clicks: 0 })
markProcessed(node)
console.log(processed.has(node)) // true
node = null // no other reference now
// eventually garbage collected; WeakMap/WeakSet entries removed too
// privateData.size and processed.size do not exist — not enumerableFollow-up Questions
- Why can WeakMap keys and WeakSet members only be objects, not primitives?
- How would you use a WeakMap to implement private class fields before # syntax existed?
- Why do WeakMap and WeakSet not support iteration or a size property?
- When would a regular Map be a better choice than a WeakMap?
MCQ Practice
1. What must a WeakMap key be?
WeakMap keys must be objects so they can be weakly referenced and garbage collected.
2. Why does WeakSet not have a size property?
Because entries may disappear at any time via garbage collection, exposing a size would be misleading.
3. What is a typical use case for WeakMap?
WeakMap is designed for auxiliary data tied to an object's lifetime, avoiding memory leaks.
Flash Cards
WeakMap holds what? — Key-value pairs where keys must be objects, held weakly.
WeakSet holds what? — A collection of unique objects, held weakly, with no values.
Why no iteration on either? — Garbage collection timing is nondeterministic, so enumeration would be unreliable.
Common use case? — Attaching private metadata or tracking membership without causing memory leaks.