jsguides

Set.prototype.isDisjointFrom()

isDisjointFrom(other)

Signature

isDisjointFrom(other)

Set.prototype.isDisjointFrom() reports whether the receiver and other share zero elements. It returns true when the two sets have no values in common and false as soon as one match is found. The method does not mutate either side.

The method is part of the ES2025 “new Set methods” proposal, which also brought intersection, union, difference, symmetricDifference, isSubsetOf, and isSupersetOf.

Parameters

other is required and accepts a Set or any set-like object. A set-like object only needs a has(value) method and a keys() method that returns an iterable; the spec only calls those two.

Passing null or undefined causes the method to throw a TypeError. The same error fires when other is a non-set-like object missing either the has or keys method.

Return value

A boolean. true means the two sets are disjoint, i.e. A ∩ B = ∅. false means they share at least one element.

The result is symmetric: a.isDisjointFrom(b) and b.isDisjointFrom(a) always return the same boolean.

Examples

Two sets with no overlap

const primes = new Set([2, 3, 5, 7, 11, 13, 17, 19]);
const squares = new Set([1, 4, 9, 16]);

console.log(primes.isDisjointFrom(squares));
// true

Primes (2, 3, 5, 7, …) and perfect squares (1, 4, 9, 16, …) share no common values, so the method returns true immediately. This is the typical case where you want to know whether two collections can be processed independently before going further.

Two sets that share elements

const composites = new Set([4, 6, 8, 9, 10, 12, 14, 15, 16, 18]);
const squares = new Set([1, 4, 9, 16]);

console.log(composites.isDisjointFrom(squares));
// false

Among composites, 4 and 9 are also perfect squares. The method returns false because the iteration finds 4 (or 9) in squares and short-circuits without checking the rest of the elements.

Empty sets are always disjoint

new Set([1, 2, 3]).isDisjointFrom(new Set());   // true
new Set().isDisjointFrom(new Set([1, 2, 3]));   // true
new Set().isDisjointFrom(new Set());            // true

An empty set has no elements, so it cannot share any with another set. The vacuous truth holds even when both sides are empty: there is simply nothing in common, and the loop has nothing to iterate.

NaN equals NaN inside a Set

Set uses SameValueZero, so NaN matches NaN:

const a = new Set([NaN]);
const b = new Set([NaN]);
a.isDisjointFrom(b); // false

This differs from regular JavaScript, where NaN !== NaN. The Set uses SameValueZero comparison for membership, which treats NaN as equal to itself, so two sets both containing NaN are not disjoint.

A set-like object as the argument

const squares = new Set([1, 4, 9, 16]);

const setLike = {
  size: 2,
  has(v) { return v === 2 || v === 5; },
  keys()  { return [2, 5].values(); },
};

squares.isDisjointFrom(setLike); // true

The argument only needs has and keys methods. Both arrays and plain objects work as long as those two methods return correct values. The receiver remains a real Set, so its internal slot is read directly without invoking user code on this.

How the algorithm works

The spec picks the smaller side to iterate so the cost is dominated by lookups against the larger side:

  1. If this is not a Set instance, throw TypeError.
  2. Validate other as a set record (needs has and keys).
  3. Compare sizes:
    • If this.size > other.size, iterate other and look each value up in this.
    • Otherwise, iterate this and look each value up in other.
  4. Return false on the first hit, true if iteration finishes without one.

This means big.isDisjointFrom(small) and small.isDisjointFrom(big) both walk the smaller set. The boolean is the same; only the work is asymmetric. If you control the call direction, call from the larger set so the smaller one is iterated.

Practical example: permission checks

A common use case is verifying that two role sets don’t overlap. You often want to know whether a user has any of the required permissions before granting access to a feature, and isDisjointFrom is the cleanest way to answer that yes-or-no question.

const requiredPermissions = new Set(['read', 'write', 'delete']);
const userPermissions = new Set(['read', 'comment']);

const userHasAny = !userPermissions.isDisjointFrom(requiredPermissions);
console.log(userHasAny);
// true  (userPermissions and requiredPermissions share 'read')

const publishOnly = new Set(['publish']);
const publishMissing = publishOnly.isDisjointFrom(requiredPermissions);
console.log(publishMissing);
// true  ('publish' is not in requiredPermissions, so the sets are disjoint)

isDisjointFrom returns true when the two sets share nothing, so combining it with a logical NOT is the idiomatic way to express “has at least one in common”. This pattern reads cleanly in code and avoids the more error-prone some() + manual lookup combination.

Edge cases and gotchas

  • this must be a real Set. Subclasses still work because they share the internal [[SetData]] slot, but Set.prototype.isDisjointFrom.call({}, ...) throws.
  • +0 and -0 are the same element, so two sets that differ only by signed zero are not disjoint.
  • NaN matches NaN, so two sets both containing NaN are not disjoint.
  • s.isDisjointFrom(s) is true only when s is empty.
  • The method never calls user has or keys on this (it reads the internal slot), but it does call them on other. A hostile set-like with expensive methods can slow this down.
  • For older runtimes, core-js and the npm package set.prototype.isdisjointfrom provide a spec-compliant polyfill.

Browser support

Available in Chrome 122+, Edge 122+, Firefox 127+, Safari 17+, Opera 108+, and Samsung Internet 26+. Not supported in IE or older Safari.

See also