mediumFrontend EngineerTechnology
What are WeakMap and WeakSet in JavaScript, and when would you use them over Map and Set?
Posted 18/04/2026
by Mehedy Hasan Ador
Question Details
Interviewer asked:
> "We're building a monitoring tool that tracks DOM elements for performance metrics. Using a regular Map caused a memory leak when elements were removed from the page. How would you fix this?"
> "We're building a monitoring tool that tracks DOM elements for performance metrics. Using a regular Map caused a memory leak when elements were removed from the page. How would you fix this?"
Suggested Solution
The Problem with Map/Set
const elementMetrics = new Map();
function trackElement(el) {
elementMetrics.set(el, { renderTime: performance.now() });
}
// When element is removed from DOM:
element.remove();
// BUT the Map still holds a strong reference → element stays in memory!
WeakMap to the Rescue
const elementMetrics = new WeakMap();
function trackElement(el) {
elementMetrics.set(el, { renderTime: performance.now() });
}
// When element is removed from DOM AND no other references exist:
element.remove();
// GC can free the element → WeakMap entry automatically disappears
Key Differences
for...of, forEach().size propertyReal-World Use Cases
1. Caching Expensive Computations
const cache = new WeakMap();
function computeExpensive(obj) {
if (cache.has(obj)) return cache.get(obj);
const result = heavyComputation(obj);
cache.set(obj, result);
return result;
}
// Cache auto-cleans when obj is garbage collected
2. Private Data for Classes
const privateData = new WeakMap();
class User {
constructor(name, secret) {
privateData.set(this, { secret });
this.name = name;
}
getSecret() { return privateData.get(this).secret; }
}
// secret cannot be accessed from outside — truly private
3. DOM Event Tracking
const handlers = new WeakMap();
button.addEventListener('click', () => { /* ... */ });
handlers.set(button, { clicks: 0, lastClick: null });
// When button is removed, tracking data auto-cleans
WeakSet
Same principle but for sets — holds weak references to objects:const activeElements = new WeakSet();
// Track "active" state without preventing GC