WeakMap and
WeakSet are two of the most
misunderstood JavaScript features.
Not because they’re hard — but because you don’t
need them every day.
When you do need them though, nothing
else fits quite as well.
I didn’t really appreciate them until I ran into memory-related issues in long-running apps. That’s when their purpose finally clicked.
🧠 What Are WeakMap and WeakSet (In Real Terms)?
Both are collections that hold weak references to objects.
That simply means:
If an object is no longer needed elsewhere, JavaScript can clean it up automatically.
No manual cleanup.
No memory leaks.
🗺️ WeakMap — Object Keys Without Memory Leaks
A WeakMap stores
key–value pairs, where
keys must be objects.
const userData = new WeakMap();
let user = { id: 1 };
userData.set(user, { lastLogin: "today" });
If user is removed:
user = null;
The data inside
WeakMap disappears
automatically.
Why this matters
- Perfect for caching
- Ideal for private data
- Safe for long-running apps
🧺 WeakSet — Tracking Objects Without Ownership
A WeakSet stores
objects only — no values.
const visitedUsers = new WeakSet();
let user = { name: "Sam" };
visitedUsers.add(user);
Once user is gone, the entry
disappears.
Use cases:
- Tracking processed objects
- Marking flags without mutating objects
- Avoiding duplicate processing
🚫 Key Limitations (Very Important)
Weak collections have restrictions — by design.
❌ You can’t iterate over them
weakMap.forEach() // ❌
❌ No size property
weakSet.size // ❌
This is intentional — JavaScript doesn’t expose garbage collection details.
⚖️ WeakMap vs Map (When to Use Which)
Use Map when:
- You need iteration
- Keys can be primitives
- You control lifecycle manually
Use WeakMap when:
- Keys are objects
- You want automatic cleanup
- Memory safety matters
Same logic applies to Set vs
WeakSet.
🚨 Common Mistakes Developers Actually Make
❌ Using primitives as keys
weakMap.set("id", 1); // ❌ error
Keys must be objects.
❌ Expecting to loop over WeakMap / WeakSet
That’s not how they’re meant to be used.
❌ Using them prematurely
If you don’t have memory concerns,
Map or
Set is usually simpler.
🧪 Advanced Insight: Private Data Pattern
Before private class fields,
WeakMap was a common privacy
tool.
const privateData = new WeakMap();
class User {
constructor(name) {
privateData.set(this, { name });
}
getName() {
return privateData.get(this).name;
}
}
This still works — and avoids accidental exposure.
Personally, I’ve used this pattern in libraries where encapsulation really mattered.
🚀 Best Practice Summary
✅ Use WeakMap for object-keyed
private data
✅ Use WeakSet to track object
presence safely
✅ Remember keys must be objects
✅ Don’t rely on iteration or size
✅ Prefer normal Map/Set
unless memory matters
0 Comments