Set.prototype.union()

Returns a new collection holding every value from either this one or another set-like object.

Signature
union(other)
  • Added in JavaScript ES2025

Parameters

ParameterTypeDescription
$otherSet | set-like objectA Set, or any set-like object: one exposing a numeric size property, a has() method taking an element and returning a boolean, and a keys() method returning an iterator of the elements.

Return value

SetA new Set containing the elements that are in this set, in other, or in both — those from this first, then those from other that are not already present.

Errors

Throws a TypeError if other is not set-like — notably for a plain array, whose length is not a size — or if called on a value that is not a real Set instance.

Changelog

  • PHP ES2025Added along with intersection(), difference(), symmetricDifference(), isSubsetOf(), isSupersetOf() and isDisjointFrom(); Baseline newly available since June 2024, so older engines need a polyfill.

union() is the mathematical A ∪ B: a brand-new collection containing everything from either side. Neither input is modified. Ordering is deterministic — all of this collection's elements first, in their insertion order, then the elements of other that were not already present, in theirs.

Before ES2025 the idiom was new Set([...a, ...b]). That still works and produces the same contents and order, but it materialises an intermediate array of every element from both sides. union() skips that allocation and reads better in a chain of set operations.

The argument is not just any iterable

This is the part that bites. other must be set-like: it needs a numeric size, a has() method and a keys() method. An array satisfies none of those — it has length, not size — so a.union([1, 2]) throws a TypeError rather than doing the obvious thing. Wrap arrays in new Set(...) first. A Map does qualify structurally, and contributes its keys.

The receiver, by contrast, must be a real Set instance; a set-like object cannot borrow this method.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Merge permissions granted by several roles into one effective collection
  • Combine tag filters from two panels without duplicating entries
  • Accumulate the distinct ids returned by several paginated responses
  • Express A or B in a chain alongside intersection() and difference()

Frequently asked questions

Why does Set union() throw a TypeError with an array?

Because the argument must be set-like — it needs size, has() and keys(), and an array has length instead of size. Convert first: a.union(new Set(arr)).

Does union() modify the original Set?

No. It returns a brand-new collection and leaves both operands exactly as they were, which is what makes calls chainable with intersection() and difference().

What can I use instead of union() in an older browser?

Use new Set([...a, ...b]), which produces identical contents in identical order. The method itself is Baseline only since June 2024, so pre-2024 engines need that form or a polyfill.

More examples

Merging role permissions

Each call returns a fresh collection, so unions chain cleanly and "read" appears once despite coming from two roles. The originals still hold exactly what they started with.

Example · javascript
const editor = new Set(["read", "write"]);
const reviewer = new Set(["read", "comment"]);
const admin = new Set(["delete"]);

const effective = editor.union(reviewer).union(admin);
console.log([...effective]);
console.log(effective.size);

// Inputs are untouched
console.log([...editor], [...reviewer]);

A custom set-like object

Anything with size, has() and keys() qualifies as other, so a hand-rolled object works without being a real Set. A Map satisfies the protocol too, and its keys() supplies "b" as the new element.

Example · javascript
const primes = {
  size: 3,
  has: (v) => [2, 3, 5].includes(v),
  keys: () => [2, 3, 5][Symbol.iterator](),
};

console.log([...new Set([1, 2]).union(primes)]);

// A Map is set-like and contributes its keys
const m = new Map([["a", 1], ["b", 2]]);
console.log([...new Set(["a"]).union(m)]);

Ordering, and the pre-ES2025 equivalent

Union is commutative in contents but not in ordering: this set's elements always come first, so a.union(b) starts with "x" and b.union(a) starts with "y". The spread-into-constructor fallback matches the result exactly and is what to use on engines predating June 2024.

Example · javascript
const a = new Set(["x", "y"]);
const b = new Set(["y", "z"]);

console.log([...a.union(b)]);
console.log([...b.union(a)]);

// Same contents and order, one extra array allocation
console.log([...new Set([...a, ...b])]);

Discussion

  • Be the first to comment on this lesson.