JavaScript Set & WeakSet
JavaScript provides two data structures for storing unordered collections of unique values, Set
and WeakSet
.
Set
We can use Set
to store unique values of any type:
const mathConstants = new Set();
We can also pass an iterable object as argument (e.g. array, string), with any duplication being removed:
const mathConstants = new Set([0, 3.14, -1, 0]);
console.log(mathConstants); // prints: Set(3) [ 0, 3.14, -1 ]
Adding & Removing Elements
New elements can be appended with add
, removed with delete
- the number of elements stored can be inspected with size
:
const mathConstants = new Set([0, 3.14, -1]);
mathConstants.add(1.61803);
mathConstants.add(1.61803); // duplicate entries will be ignored
mathConstants.delete(-1);
console.log(mathConstants); // prints: [ 0, 3.14, 1.61803 ]
console.log(mathConstants.size); // prints: 3
Checking for Element Existence
const mathConstants = new Set([0, 3.14, -1]);
console.log(mathConstants.has(3.14)); // prints: true
console.log(mathConstants.has(1.41)); // prints: false
No index but guaranteed order
Unlike an array, a Set object does not have an index. However, the order of elements in a Set object is guaranteed to be insertion order - new elements are added to the end of the Set.
Iteration
const mathConstants = new Set([0, 3.14, -1, 0]);
for (const value of mathConstants) {
console.log(value);
}
mathConstants.forEach((value) => {
console.log(value);
});
WeakSet
const mathConstants = new WeakSet();
const pi = {
name: 'PI',
value: 3.14159
};
mathConstants.add(pi);
console.log(mathConstants); // prints: WeakSet [ { ... } ]
The WeakSet
object is similar to the Set
object, but with some differences:
No Primitives
WeakSet
values must be objects, with primitive values such as numbers or strings are not allowed.
Weakly Held Objects
When a WeakSet
object is created, memory is allocated to store the object but unlike a regular Set
object, the values are not strongly held. This means that if there are no other references to a value in the program, the object may be garbage collected by the JavaScript engine. When a key is garbage collected, its associated value is also removed from the WeakSet
object.
Other Limitations
WeakSet
objects do not have a size
property or any other way to get the number of values they contain.
Moreover, WeakSet
objects are not enumerable - we cannot use a for...in
loop.
WeakSet
is pretty limited in functionality - pretty much the only thing you can do is check if a WeakSet
contains an object:
const mathConstants = new WeakSet();
const pi = {
name: 'PI',
value: 3.14159
};
mathConstants.add(pi);
const tau = {
name: 'tau',
value: 6.28318
};
console.log(mathConstants.has(pi)); // prints: true
console.log(mathConstants.has(tau)); // prints: false