JavaScript: WeakMap vs. Map & WeakSet vs. Set
An essential JavaScript memory management and architecture interview question is:
What are WeakMap and WeakSet in JavaScript? How do they differ from Map and Set, and what specific problem do they solve regarding garbage collection?
Modern web applications handle complex data mappings and caching layers. If not managed carefully, storing metadata about objects (like DOM nodes) in global maps can easily lead to severe memory leaks. WeakMap and WeakSet provide a way to store data relationships without blocking garbage collection.
1. The Core Limitation of Standard Maps
A standard JavaScript Map holds strong references to both its keys and values.
If an object is used as a key in a standard Map, that object cannot be garbage collected—even if all other references to it have been deleted from the application:
let user = { name: "John" };
const userMap = new Map();
userMap.set(user, "metadata"); // Strong reference created
user = null; // Remove direct reference
// At this point, the object { name: "John" } is STILL stored in memory.
// It cannot be garbage collected because the Map still holds a strong key reference!To free this memory, you must explicitly call userMap.delete(key) or clear the Map. Forgetting to do so results in a memory leak.
2. How WeakMap Solves This
A WeakMap holds weak references to its keys.
If a key object inside a WeakMap has no other active references pointing to it, the JavaScript engine's garbage collector will automatically collect the object and remove its key-value entry from the WeakMap:
let user = { name: "John" };
const userWeakMap = new WeakMap();
userWeakMap.set(user, "metadata"); // Weak reference created
user = null; // Remove direct reference
// The object { name: "John" } is now eligible for immediate garbage collection!
// When garbage collected, its entry in userWeakMap is cleaned up automatically.3. Key Differences Summary
| Feature | Map | WeakMap |
|---|---|---|
| Key Types | Any type (primitives, objects, functions) | Objects only (no primitives like strings/numbers) |
| Reference Type | Strong reference to keys | Weak reference to keys |
| Garbage Collection | Prevents keys from being collected | Allows keys to be garbage collected |
| Iterability | Yes (has .keys(), .values(), .entries(), size) | No (not iterable, no .forEach(), no size) |
| Use Cases | General key-value storage, caching | Private data, DOM metadata cache |
Note: The same differences apply to Set vs WeakSet. A WeakSet holds weak references to objects, cannot store primitives, and is not iterable.
4. Key Use Cases for WeakMap
A. Attaching Metadata to DOM Nodes
If you attach metadata (like UI states or click statistics) to DOM elements using a standard Map, deleting the DOM elements from the page will not free their memory because the Map still references them. WeakMap avoids this completely:
const nodeMetadata = new WeakMap();
function attachData(element) {
nodeMetadata.set(element, { clicks: 0 });
}
// When the element is removed from the DOM and deleted,
// the metadata is garbage collected automatically!B. Private Object Data (Encapsulation)
You can store private variables outside of class structures without creating memory leaks:
const privateData = new WeakMap();
class User {
constructor(id, secret) {
this.id = id;
privateData.set(this, { secret });
}
getSecret() {
return privateData.get(this).secret;
}
}Senior-Level Interview Answer
The fundamental difference between
MapandWeakMapis the reference strength of keys. AMapestablishes strong references, preventing garbage collection of key objects. AWeakMapholds weak references to its keys, meaning if a key object lacks other active references in the execution stack, it is garbage collected, and its entry is cleared from the WeakMap automatically. To make this garbage collection lookup deterministic,WeakMapkeys must be object types rather than primitive values, and the collection is non-iterable, preventing exposure of intermediate garbage collection states. Major use cases include metadata association for DOM nodes, private scoping structures, and non-blocking caching layers.
Common Interview Mistakes
❌ Attempting to use primitive keys in WeakMap
Writing weakMap.set('user_123', data) will throw a TypeError: Invalid value used as weak map key. Keys must be object references or symbols because primitive values (like strings, numbers, or booleans) are not garbage collected in the same manner.
❌ Trying to iterate or check the size of a WeakMap
Assuming you can print all items using a loop. Because the garbage collector runs non-deterministically in JS engines, exposing a .size or iterator on WeakMap would leak compiler/GC details, which is why iteration is completely disabled.
Key Takeaways
- Weak Reference: WeakMap and WeakSet hold weak references to object keys, allowing garbage collection to clean them up.
- Leak Prevention: Using them prevents memory leaks when caching metadata for elements that might be deleted (e.g. DOM nodes).
- Object Only: Keys in a WeakMap and elements in a WeakSet must be objects or symbols; primitive values are rejected.
- Non-Iterable: Due to garbage collection nondeterminism, WeakMap and WeakSet cannot be looped or queried for size.
- Data Scoping: Useful for maintaining private class fields, dynamic caches, and external node mappings safely.