JavaScript Set
by Kuligaposten 2026-08-27
The Set object lets you store unique values of any type and offers a cleaner, faster way to handle uniqueness than arrays.
Understanding JavaScript's Set Object
Before Set existed, deduplicating an array or checking for membership usually meant reaching for indexOf() or building a lookup object by hand. The Set object, introduced in ES6, gives JavaScript a built-in collection type designed specifically for storing unique values. This post covers what Set is, how it works, and when to reach for it over an array.
What is a Set?
A Set is a collection of values where each value may occur only once. Values can be primitives (numbers, strings, booleans) or object references, and a Set remembers insertion order when you iterate over it.
Syntax
new Set([iterable]);
- iterable (optional): An array or any iterable whose elements are added to the new
Set. Duplicate values are automatically dropped.
const numbers = new Set([1, 2, 2, 3, 3, 3]);
console.log(numbers); // Set(3) {1, 2, 3}
Core Methods and Properties
| Member | Description |
|---|---|
add(value) | Adds a value to the set. Returns the set, so calls can be chained. |
delete(value) | Removes a value. Returns true if it existed, false otherwise. |
has(value) | Checks whether a value exists. Returns a boolean. |
clear() | Removes all values from the set. |
size | A property (not a method) with the number of values. |
const colors = new Set();
colors.add("red").add("green").add("blue");
console.log(colors.has("green")); // true
console.log(colors.size); // 3
colors.delete("red");
console.log(colors.size); // 2
Uniqueness Uses SameValueZero
Set determines uniqueness using the "SameValueZero" algorithm, which is like strict equality (===) except that NaN is considered equal to itself.
const s = new Set([NaN, NaN, 1, "1"]);
console.log(s); // Set(3) {NaN, 1, '1'}
Note that 1 and '1' are different values because a Set does not perform type coercion. Object references are compared by identity, not by content:
const s = new Set();
s.add({ id: 1 });
s.add({ id: 1 });
console.log(s.size); // 2 - different object references
Iterating a Set
Sets are iterable, so you can use for...of, the spread operator, or forEach():
const letters = new Set(["a", "b", "c"]);
for (const letter of letters) {
console.log(letter);
}
letters.forEach((letter) => console.log(letter));
console.log([...letters]); // ['a', 'b', 'c']
Insertion order is preserved, which makes Set predictable to work with, unlike plain objects in some edge cases.
Practical Use Cases
Removing Duplicates from an Array
The most common use case: converting an array to a Set and back removes duplicates in one line.
const numbers = [1, 2, 2, 3, 4, 4, 5];
const unique = [...new Set(numbers)];
console.log(unique); // [1, 2, 3, 4, 5]
Fast Membership Checks
Set.prototype.has() runs in average O(1) time, making it far faster than Array.prototype.includes() for large collections.
const visitedIds = new Set();
function markVisited(id) {
visitedIds.add(id);
}
function isVisited(id) {
return visitedIds.has(id);
}
markVisited(42);
console.log(isVisited(42)); // true
console.log(isVisited(99)); // false
Set Operations
You can implement classic set math using array methods combined with Set:
const a = new Set([1, 2, 3, 4]);
const b = new Set([3, 4, 5, 6]);
// Union
const union = new Set([...a, ...b]);
console.log(union); // Set(6) {1, 2, 3, 4, 5, 6}
// Intersection
const intersection = new Set([...a].filter((x) => b.has(x)));
console.log(intersection); // Set(2) {3, 4}
// Difference (a - b)
const difference = new Set([...a].filter((x) => !b.has(x)));
console.log(difference); // Set(2) {1, 2}
Set vs. Array
| Set | Array | |
|---|---|---|
| Duplicate values | Not allowed | Allowed |
| Membership check | has() — average O(1) | includes() — O(n) |
| Order | Insertion order preserved | Index order |
| Access by index | Not supported | Supported |
| Built-in methods | add, delete, has, clear | map, filter, reduce, etc. |
Use Set when uniqueness matters or you need frequent existence checks. Use an array when you need indexed access or the rich array method ecosystem (map, filter, reduce).
WeakSet: A Related Structure
JavaScript also provides WeakSet, a variant that only stores objects (not primitives) and holds them weakly, meaning entries can be garbage-collected if there are no other references to them. Unlike Set, WeakSet is not iterable and has no size property, which makes it suitable for tracking objects (like DOM nodes) without preventing memory cleanup.
const tracked = new WeakSet();
let el = { name: "button" };
tracked.add(el);
console.log(tracked.has(el)); // true
el = null; // eligible for garbage collection, and removed from the WeakSet
Common Pitfalls
- Expecting index access:
Sethas noset[0]. Convert to an array first if you need indexing.
const s = new Set(["a", "b", "c"]);
console.log(s[0]); // undefined
console.log([...s][0]); // 'a'
Assuming objects with the same shape are equal: As shown earlier, two objects with identical properties are still distinct entries.
Forgetting that
sizeis a property, not a method:
console.log(colors.size()); // TypeError: colors.size is not a function
console.log(colors.size); // correct
Conclusion
Set gives JavaScript a purpose-built tool for uniqueness and fast lookups, cases that used to require workarounds with arrays or objects. Whether you're deduplicating data, tracking visited items, or performing set algebra like unions and intersections, Set (and its weak counterpart, WeakSet) is a clean, efficient addition to your data structure toolbox.