Question presented to candidate: "JavaScript Sets now have union, intersection, difference, symmetricDifference, isSubsetOf, isSupersetOf, and isDisjointFrom built in. When, if ever, do these actually outperform a manual loop with .has(), and are there real correctness differences beyond just convenience?"
What a strong answer should cover:
- All seven methods return a brand-new Set and never mutate either operand — verified directly; this makes them safe to use on Sets that must stay referentially stable, like Redux-style state.
- Every method accepts any "set-like" object — something with a numeric .size, a .has(value) method, and a .keys() iterator — not just a real Set instance. Verified: a hand-built plain object satisfying that shape works, while a plain Array, which has no .size, throws a TypeError.
- SameValueZero equality is used throughout, the same as Set.prototype.has: NaN is treated as equal to itself, and -0/+0 are treated as the same value — verified directly.
- Performance is genuinely method-dependent, not a flat percentage. Verified: intersection() beats a manual loop by a modest ~1.2x, union() beats a naive new Set([...a, ...b]) by over 3x by avoiding one large intermediate array, and isDisjointFrom() can be dramatically faster than manually building a full intersection just to check its size — thousands of times faster in a best-case early-match scenario, because it short-circuits on the first shared element.
- The real headline is avoiding intermediate allocations, not raw CPU speed: intersection() and union() never materialize an intermediate Array the way [...a].filter(...) or [...a, ...b] do.
Clarifying questions expected:
- "Does the hot path need a boolean answer only, like whether these overlap at all, or the actual overlapping elements?" — isSubsetOf/isSupersetOf/isDisjointFrom avoid allocating a result Set entirely when only a yes/no answer is needed.
- "Are the input Sets roughly the same size, or is one much smaller?" — every one of these methods is specified to iterate the smaller operand internally, so size skew changes the real-world cost more than which method is chosen.
Code / implementation expected: Yes — real, executed benchmarks comparing native Set methods against hand-rolled loop equivalents at meaningful scale, not assumed percentages.