new Set()
Creates a collection that stores each value only once, optionally filled from any iterable.
new Set()
new Set(iterable)- Added in JavaScript ES2015
Parameters
| Parameter | Type | Description |
|---|---|---|
$iterableoptional | Iterable | null | undefined= undefined | An iterable object (such as an array or a string) whose elements are all added to the new Set. Duplicates collapse. If omitted, null, or undefined, the new Set is empty. |
Return value
SetA new Set object containing the unique values drawn from iterable, or empty if none was given.
Errors
Throws a TypeError if called without new, or if the argument is not null/undefined and is not iterable.
A Set holds values, not key/value pairs, and refuses to hold the same value twice. Membership is decided by SameValueZero: the same rule as === except that NaN equals itself, and 0 and -0 are treated as one value. Objects are compared by reference, so two structurally identical object literals are two different members.
Reach for it when you need a growing pile of "things I have already seen" — visited node ids, tags a user has picked, error codes collected during a run — and you will be asking "is this in there?" more than once. The membership check is required by the specification to be sublinear, so it beats scanning an array as the collection grows.
The construction-from-iterable form gives you the dedupe idiom that everyone actually looks this page up for:
const unique = [...new Set(values)];
That round-trip preserves first-seen order, which sorting-based dedupe does not.
What it is not
It is not an array. There is no index, no map, no filter, no length. Convert with spread or Array.from() when you need those, and remember that the conversion copies — mutating the array will not touch the original collection.
Example
When to use it
- Strip duplicate ids out of a list returned by two merged API calls
- Track which graph nodes a traversal has already visited
- Build a stop-word or allow-list you will test against repeatedly
- Count how many distinct characters or words appear in a string
Frequently asked questions
How do I remove duplicates from an array in JavaScript?
Wrap it in a Set and spread it back: [...new Set(arr)]. The Set discards repeats and the spread restores an array in first-seen order, all in one expression.
Why does a Set not remove duplicate objects?
Because objects are compared by reference, not by contents, so {id:1} and {id:1} are two distinct values. Dedupe by a primitive key (an id, or JSON.stringify output) instead.
Is a Set faster than an array for lookups?
Yes for membership tests — the specification requires access times sublinear in the number of elements, so has() beats Array.prototype.includes() on collections of any real size. Arrays remain better for indexed access and ordered slicing.
More examples
Dedupe objects by a key
Because object references never collapse on their own, the working pattern is to keep a Set of primitive keys alongside the filter. The first row with a given id wins, and the output shows the duplicate id 7 row dropped while insertion order survives.
const rows = [
{ id: 7, name: "ada" },
{ id: 7, name: "ada (dup)" },
{ id: 9, name: "grace" },
];
const seen = new Set();
const deduped = rows.filter((row) => {
if (seen.has(row.id)) return false;
seen.add(row.id);
return true;
});
console.log(deduped.map((r) => r.name));
console.log([...seen]);SameValueZero, not strict equality
Size is 4: the two NaN values collapse into one, 0 and -0 collapse into one (stored as the first inserted, 0), and "1" and 1 stay separate because no type coercion happens. Note that indexOf still cannot find NaN while the Set can.
const s = new Set([NaN, NaN, 0, -0, "1", 1]);
console.log(s.size);
console.log([...s]);
// Arrays disagree about NaN
console.log([NaN].includes(NaN), [NaN].indexOf(NaN));
console.log(s.has(NaN));Copying and set algebra on construction
Passing a Set to the constructor makes a shallow copy — a separate object, so adding to the copy leaves the original at two members. Spreading several iterables into one array before constructing is the pre-ES2025 way to union collections.
const original = new Set(["a", "b"]);
const copy = new Set(original);
copy.add("c");
console.log([...original], [...copy]);
console.log(original === copy);
// Concatenating iterables before deduping
const merged = new Set([...original, ...copy, "a"]);
console.log([...merged], merged.size);
Discussion