Lesson 41: Mastering JavaScript WeakMap and WeakSet with challenges!

manoj ymkmanoj ymk
6 min read

✅ What are WeakMap and WeakSet?

They are special memory-friendly versions of Map and Set where:

  • Keys (in WeakMap) or values (in WeakSet) must be objects onlyno primitives allowed.

  • These structures don’t prevent garbage collection — if no other references to the object exist, the key/value is automatically removed.

  • They are not iterable and have limited APIs.


📦 WeakMap

const weakMap = new WeakMap();
let user = { name: 'John' };

weakMap.set(user, 'some metadata');
user = null; // The object becomes unreachable → garbage collected → entry removed

📦 WeakSet

const weakSet = new WeakSet();
let user = { name: 'Alice' };

weakSet.add(user);
user = null; // Entry is removed once object is unreachable

✅ Why They Matter

They solve key memory leak problems when:

  • You attach ephemeral metadata to DOM elements or objects.

  • You implement caches or tracking where the data should vanish once the object does.


🚫 Limitations

FeatureWeakMap / WeakSet
.size❌ Not supported
.keys()❌ Not supported
.clear()❌ Not supported
Iteration❌ Not supported
Primitives❌ Not allowed

This is because internal entries can vanish at any moment, so listing them is unreliable.


🔹 2. Fill Any Gaps (Hidden Mechanics, Edge Cases)

🧩 Internal Mechanics

  • WeakMap keys and WeakSet values use weak references.

  • These do not appear in the reachability graph, so GC can clean them.

  • JavaScript doesn’t expose when GC happens. It may delay cleanups.


🔥 Common Developer Mistakes

  1. Trying to iterate over a WeakMap/WeakSet:

     for (let key of weakMap) // ❌ TypeError
    
  2. Using primitive keys:

     weakMap.set('str', 123); // ❌ Invalid — only objects
    
  3. Assuming size or presence after GC:

     console.log(weakMap.size); // ❌ Doesn’t exist
    

🧪 Hidden Quirks

  • WeakMap keys are compared by object identity, not deep value.

  • You can’t force cleanup — useful in dev tools but unreliable in prod.


🧠 Pro Insight: Use with DOM elements

For attaching metadata without risking memory leaks:

const elementMeta = new WeakMap();
elementMeta.set(domNode, { clicked: true });

When domNode is removed from DOM and unreachable, entry disappears.


🔹 3. Challenge Me Deeply

🟢 Basic

  1. Create a WeakMap and use an object key to store user data.

  2. Use a WeakSet to track visited user objects. Check for membership.

  3. Demonstrate a memory-safe metadata attachment to a DOM element.

🟡 Intermediate

  1. Build a cache using WeakMap that stores expensive computations per object.

  2. Write a function trackVisits(user) using WeakMap where count auto-vanishes.

  3. Try setting a primitive key in a WeakMap. Catch and explain the error.

  4. Simulate a bug where iterating over WeakMap is attempted — and debug it.

🔴 Advanced

  1. Design a third-party library interface that uses WeakMap to hide internal state from users.

  2. Compare behavior of a Map and WeakMap in terms of garbage collection (use Chrome dev tools memory panel).

  3. Emulate the concept of private fields using WeakMap to encapsulate object internals.

🎯 Brain Twister

  1. Why does this code seem to leak memory, even when using a WeakMap?
let john = { name: "John" };
let weakMap = new WeakMap();
(function wrapper() {
  weakMap.set(john, "data");
})();
// john = null; is *not* called. Why is entry not collected?

🔹 4. Interview-Ready Questions

✅ Conceptual

  • What’s the difference between Map vs WeakMap?

  • Why are WeakMap/WeakSet not iterable?

  • When would you prefer WeakMap over Map?

✅ Scenario-Based

  • Suppose you’re tracking event listeners on DOM elements. How would you ensure no memory leaks using WeakMap?

  • You’re storing per-user session data. How can WeakMap help prevent stale data?

✅ Debugging-Style

  • You get a “memory leak” in a caching layer. You used Map. What would you change?

  • Why can’t your code list entries in your WeakMap?

✅ Best Practices

👍 Good🚫 Bad
Use WeakMap for metadataUse WeakMap like a regular map
Avoid holding extra refs to keysUse primitive keys
Use with DOM or 3rd-party objectsRely on iteration methods

🔹 5. Real-World Usage

🔧 Front-End

  • 🔍 DOM Element Tracking: Attach hidden data to DOM nodes (React refs, observers).

  • 🧠 Tooltips/Popups: Link metadata (like open state) to specific elements.

🔧 Back-End

  • 🗝️ Private data for user/session objects in Node.js modules.

  • 📦 Caching in ORM layers (MongoDB, Sequelize, etc.) tied to model objects.

🧰 Libraries

  • React DevTools and Vue DevTools use WeakMap internally to track component metadata.

  • jQuery internally used object maps for similar effects (pre-ES6).


🔹 6. Remember Like a Pro

🧠 Mnemonic

“Weak = Fleeting Friendships”
Just like a flaky friend, these collections don’t hold on — once the object is gone, the entry disappears.


🧾 Cheatsheet

FeatureMapWeakMap
Keys typeAnyObjects only
Iterable✅ Yes❌ No
.size
Garbage-safe
Use casePersistent dataEphemeral, auto-cleared data

🔹 7. Apply It in a Fun Way

🧩 Mini Project: “Spy Tracker”

Goal: Track which secret agents (objects) visit your HQ. Once they’re gone (unreachable), you forget they were ever there.


👣 Steps:

  1. Create a WeakMap called spyVisitLog.

  2. Each spy object (e.g. { codename: "X" }) is logged with a timestamp.

  3. Add a logVisit(spy) function to store the timestamp.

  4. Simulate spy = null after a delay.

  5. Periodically check and log (faked) memory usage.

  6. Show how the entry disappears automatically.


➕ Extensions

  • Add a WeakSet to store “suspicious” agents.

  • Build a UI to track which DOM nodes had events, and auto-clean as removed.


🧠 Optional (Extra Value)

💥 Common Mistakes

  • Trying to “clear” a WeakMap — not possible.

  • Logging or expecting consistent contents — can vanish anytime.

⚡ Performance Tips

  • WeakMap avoids manual cleanup, reducing code complexity and memory leaks.

  • Use it when data lifespan should be tied to an object’s lifecycle.

🧱 Modern Alternatives

  • Private class fields (#private) can sometimes replace WeakMap for encapsulation.

  • Use FinalizationRegistry (advanced) if you need to run code when object is GC’d.

0
Subscribe to my newsletter

Read articles from manoj ymk directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

manoj ymk
manoj ymk