WeakMap and WeakSet in Javascript
Tue Nov 14 2023
In the JavaScript engine, garbage collection is phenomenal. Whenever an object is created, it is given a reference so that the JavaScript engine can recognize its usage. When the reference is modified or removed, the garbage collector smartly identifies this change, allowing it to promptly remove the object from memory. This ensures optimal performance and efficient resource utilization.
let john = { name: "John" }; // the object can be accessed, john is the reference to it
// overwrite the reference
john = null;
// the object will be removed from memory
For instance, if we put an object into an Map, then while the Map is alive, the object will be alive as well, even if there are no other references to it.
let john = { name: "John Doe" };
const map = new Map();
map.set(john, "secret documents");
john = null;
So in above example john
object is created and put inside map
key then when we try making john to null that doesnot mean it will be garbage collected.
Because in map
key mapping to that john
object which means that garbage collection of that object wont happen.
Note :
WeakMap and WeakSet doesnot accept any primitives, it will throw error if tried.
WeakMap
The first difference between Map and WeakMap is that keys must be objects, not primitive values:
const map = new WeakMap();
weakMap.set("test", "Oops!"); // Error "test" is not an object
Now, if we use an object as the key in it, and there are no other references to that object then it will be removed from memory (and from the map) automatically.
let john = { name: "John" };
let weakMap = new WeakMap();
weakMap.set(john, "...");
john = null; // overwrite the reference
// john is removed from memory and also from map automatically.
Compare it with the regular Map example above. Now if john only exists as the key of WeakMap – it will be automatically deleted from the map (and memory).
WeakMap does not support iteration and methods keys()
, values()
, entries()
, so there’s no way to get all keys or values from it.
WeakMap has only the following methods:
weakMap.set(key, value)
weakMap.get(key)
weakMap.delete(key)
weakMap.has(key)
Real life use case :
weakMap.set(john, "secret documents");
// if john dies, secret documents will be destroyed automatically
WeakSet
A WeakSet behaves similarly to a WeakMap; the only difference is that it does not associate a value with an object key
- It is analogous to Set, but we may only add objects to WeakSet (not primitives).
- Like Set, it supports
add()
,has()
anddelete()
, but notsize
,keys()
and no iterations.
For instance, we can add users to WeakSet to keep track of those who visited our site:
let visitedSet = new WeakSet();
let john = { name: "John" };
let pete = { name: "Pete" };
let mary = { name: "Mary" };
visitedSet.add(john); // John visited us
visitedSet.add(pete); // Then Pete
visitedSet.add(john); // John again
// visitedSet has 2 users now
// check if John visited?
alert(visitedSet.has(john)); // true
// check if Mary visited?
alert(visitedSet.has(mary)); // false
john = null;
// visitedSet will be cleaned automatically
Conclusion
WeakMap
is Map
like collection that
allows only objects as keys and removes them together with associated value once
they become inaccessible by other means.
WeakSet
is Set
like collection that
stores only objects and removes them once they become inaccessible by other means.
Their main advantages are that they have weak references to objects, so they can easily be removed by garbage collector. That comes at the cost of not having support for clear, size, keys, values…