Set (and WeakSet)

A Set object stores unique values of any type (including primitives). A WeakSet object stores unique objects.

References to objects in a WeakSet collection are held weakly. If there is no other reference to an object stored in the WeakSet, it can be garbage-collected. This means memory leak can be avoided. That also means that there is no list of current objects stored in the collection. A WeakSet is not enumerable, making it a good choice for keeping private data, as an outsider won't be able to list and inspect its contents.A Set has the following properties and methods:

Set.prototype.size

Returns the number of values in the Set object.

Set.prototype.clear()

Removes all elements from the Set object.

Set.prototype.forEach(callbackFn[, thisArg])

Calls callbackFn once for each value present in the Set object, in insertion order. If a thisArg parameter is provided to forEach, it will be used as the 'this' value for each callback.

This shows how to merge Sets/Maps.
var s1 = new Set([
  ...(new Set([1, 2, 3])),
  ...(new Set([4, 5, 6]))
]);
console.log(s1.size);

6

The following three methods are also shared by WeakSet:

Set.prototype.has(value)

Returns a boolean asserting whether an element is present with the given value in the Set object or not.

Set.prototype.add(value)

Appends a new element with the given value to the Set object. Returns the Set object.

Set.prototype.delete(value)

Removes the element associated with the value and returns the value that Set.prototype.has(value) would have previously returned. Set.prototype.has(value) will return false afterwards.


var o = {};
var s = new Set("hi");   // accepts any iterable value
console.log(s.size);

s.add('h');
console.log(s.size);

s.add(o);
console.log(s.size);

s.add(o);
console.log(s.size);

s.add({});
console.log(s.size);

s.add({});
console.log(s.size);

s.add(NaN);
console.log(s.size);

s.add(NaN);
console.log(s.size);

s.forEach((v) => {
  console.log(v);
});

2 2 3 3 4 5 6 6 h i Object Object Object NaN

var ws = new WeakSet();
var o = {};

ws.add([1, 2]);
console.log(ws.has([1, 2]));

ws.add(o);
ws.add(o);
ws.delete(o);
console.log(ws.has(o));

false false
This shows how to obtain the last value added to a Set.
var s = new Set([1, 2, 3]);
s.add(10);

var lastValue = Array.from(s).pop();
console.log(lastValue);

10
Testing for equality of Sets is not so straightforward.
var a = new Set([1, 2, 3]);
var b = new Set([1, 3, 2]);
alert(eqSet(a, b));

function eqSet(as, bs) {
  if (as.size !== bs.size) return false;
  for (var a of as) if (!bs.has(a)) return false;
  return true;
}

true

For information about the following three methods, refer to 8.12.4.

Set.prototype.keys()

Set.prototype.values()

Set.prototype.entries()

A Set allows duplicates to be removed from an array.
var a = ['a', 'b', 'a'];
console.log(Array.from((new Set(a)).values()));

["a", "b"]
These are some ways to stringify an array-like Set, or an iterable in general.
JSON.stringify([...s]);
JSON.stringify([...s.keys()]);
JSON.stringify([...s.values()]);
JSON.stringify(Array.from(s));
JSON.stringify(Array.from(s.keys()));
JSON.stringify(Array.from(s.values()));

ECMAScript 2025 added seven mathematical set-operation methods to Set.prototype, finally making Set-to-Set comparisons a one-liner instead of a manual loop (recall the eqSet() helper above). Each accepts any 'set-like' object (anything with a numeric .size and a .has() method, not necessarily a real Set) as its argument.

Set.prototype.union(other) elements in this Set or other
Set.prototype.intersection(other) elements in both this Set and other
Set.prototype.difference(other) elements in this Set but not in other
Set.prototype.symmetricDifference(other) elements in exactly one of the two sets
Set.prototype.isSubsetOf(other) true if every element of this Set is in other
Set.prototype.isSupersetOf(other) true if every element of other is in this Set
Set.prototype.isDisjointFrom(other) true if the two sets share no elements

var odds = new Set([1, 3, 5, 7]);
var primes = new Set([2, 3, 5, 7]);

console.log([...odds.union(primes)]);
console.log([...odds.intersection(primes)]);
console.log([...odds.difference(primes)]);
console.log([...odds.symmetricDifference(primes)]);
console.log(new Set([3, 5]).isSubsetOf(odds));
console.log(odds.isSupersetOf(new Set([3, 5])));
console.log(odds.isDisjointFrom(new Set([2, 4])));

[1, 3, 5, 7, 2] [3, 5, 7] [1] [1, 2] true true true