WeakMap vs Map
The difference between Map and WeakMap in JavaScript is fundamental: both store "key to value" pairs, but WeakMap is built for the special case where you need to associate data with objects without preventing the garbage collector (GC) from reclaiming those objects.
Theory
TL;DR
Mapkeys can be any value,WeakMapkeys are objects only.- A
Mapholds its keys with strong references, aWeakMapholds them weakly. - A
WeakMapcannot be iterated: there is nosize,keys(),values(),entries()orforEach(). - A key object that is unreachable from outside disappears from the
WeakMapautomatically, along with its value. WeakMapmethods:set,get,has,delete.- Typical tasks: private class data, a leak free cache, internal marks on objects.
Quick example
First a Map:
const map = new Map();
let user = { name: 'Alice' };
map.set(user, 'User data');
console.log(map.get(user)); // "User data"
user = null; // drop the reference
console.log(map); // the Map still holds { name: "Alice" }The object will not be removed from memory while the Map keeps a reference to it, and that is precisely a memory leak.
Now a WeakMap:
const weakMap = new WeakMap();
let user = { name: 'Alice' };
weakMap.set(user, 'User data');
console.log(weakMap.has(user)); // true
user = null; // the object becomes unreachable
// the object will be removed automatically by the garbage collectorWhat happens here:
- Once the object is no longer reachable from code, the garbage collector removes both the object and its entry in the
WeakMap. - A
WeakMapnever stands in the way of memory cleanup.
The main difference
| Property | Map | WeakMap |
|---|---|---|
| Keys | any values (strings, numbers, objects) | objects only |
| Reference type | strong (the object lives while a reference exists) | weak (the GC may remove the object) |
Iteration (for...of, .keys(), .size) | available | not available |
| Size check | .size | not available |
| Use case | general purpose key value pairs | temporary bindings to objects |
What a "weak reference" means
A weak reference is a reference that does not prevent the garbage collector from removing an object when no other, strong references to it remain.
In a regular Map keys are held strongly: while the Map itself exists, all of its keys and values stay in memory. In a WeakMap that is not the case, the GC may clear them at any moment.
That is exactly why a WeakMap refuses to be iterated: its set of keys changes unpredictably, outside the control of your code, so any traversal would be non deterministic.
WeakMap methods
| Method | Description |
|---|---|
set(key, value) | store a value for an object |
get(key) | read the value |
has(key) | check for presence |
delete(key) | remove the entry |
There is no size, keys(), values(), entries() or forEach(), because a WeakMap is not iterable.
Practical uses
Storing private data for objects:
const privateData = new WeakMap();
class User {
constructor(name, age) {
privateData.set(this, { age });
this.name = name;
}
getAge() {
return privateData.get(this).age;
}
}
const alice = new User('Alice', 30);
console.log(alice.getAge()); // 30
// once alice is gone, the object and its private data leave memoryTwo benefits apply at once here:
- the private data is invisible from the outside,
- it is cleaned up automatically when the object is collected.
Caching:
const cache = new WeakMap();
function getData(obj) {
if (!cache.has(obj)) {
const data = Math.random(); // assume this is expensive to compute
cache.set(obj, data);
}
return cache.get(obj);
}
let user = {};
console.log(getData(user)); // the cache entry is created
user = null; // the object and its cache entry are cleared automaticallyIdeal for holding computed data temporarily with no memory leaks.
In short:
| Property | Map | WeakMap |
|---|---|---|
| Key types | any | objects only |
| Iterating elements | available | not available |
| Binding to objects | strong | weak |
| Automatic removal | no | yes |
| Use case | caches, dictionaries, configs | private data, leak free caches |
Common mistakes
- Using a primitive as a
WeakMapkey.weakMap.set('id', 1)throws aTypeError, only an object can be a key. - Looking for
sizeor a loop over aWeakMap. They are absent by design; if you need a list of keys, only aMapfits. - Treating a
Mapas a safe object cache. While theMaplives, so do all of its keys, the most common source of leaks in long running applications. - Expecting instant cleanup. The GC runs on its own schedule, so right after
user = nullthe entry may still exist. - Confusing it with
WeakSet. AWeakMapstores "object to value" pairs, aWeakSetstores only the objects themselves, with no values. - Keeping a strong reference to the key inside the value. If the value reaches its own key through another strong chain, the object never leaves memory.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.