support@90-10.dev

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