DEV Community

Maxim Logunov
Maxim Logunov

Posted on

Set.has() vs. Array.includes(): When and Why to Use Each

Introduction

When working with JavaScript collections, developers often need to check whether a value exists within a data structure. Two common methods for this are Set.has() and Array.includes(). While both serve similar purposes, they have important differences in performance and use cases that every JavaScript developer should understand.

Understanding the Basics

Array.includes()

const fruits = ['apple', 'banana', 'orange'];
console.log(fruits.includes('banana')); // true
Enter fullscreen mode Exit fullscreen mode

The Array.includes() method checks if an array contains a specified element, returning true or false. It performs a linear search through the array.

Set.has()

const fruitSet = new Set(['apple', 'banana', 'orange']);
console.log(fruitSet.has('banana')); // true
Enter fullscreen mode Exit fullscreen mode

Set.has() checks if a value exists in a Set object. Sets store unique values and provide faster lookup times than arrays.

Performance Comparison

The most significant difference between these methods is their performance characteristics:

  • Array.includes(): O(n) time complexity (linear time)

    • Must potentially check every element in the array
    • Performance degrades as array size increases
  • Set.has(): O(1) time complexity (constant time) on average

    • Uses a hash table implementation
    • Lookup time remains nearly constant regardless of Set size

Benchmark Example

For a collection with 1,000,000 elements:

  • Set.has() might take ~0.01ms
  • Array.includes() might take ~5ms (500x slower)

Pros and Cons

Set.has() Pros

  1. Much faster for large collections
  2. Automatically handles uniqueness (no duplicate values)
  3. Cleaner semantics when working with unique values
  4. Better for frequent membership tests

Set.has() Cons

  1. Requires conversion if starting with an array (new Set(array))
  2. No index access like arrays have
  3. Slightly more memory usage due to hash table overhead
  4. Insertion order is maintained but not as reliably indexable as arrays

Array.includes() Pros

  1. Works directly on arrays (no conversion needed)
  2. Preserves order and allows index access
  3. Allows duplicates (when needed)
  4. More familiar to many developers

Array.includes() Cons

  1. Slower for large collections
  2. No built-in uniqueness guarantee
  3. Less efficient for repeated lookups

When to Use Each

Use Set.has() when:

  • You're working with unique values
  • You need to perform many membership tests
  • The collection is large (typically > 100 elements)
  • You don't need array-specific features like indexing

Use Array.includes() when:

  • You're already working with an array
  • You need to preserve duplicates or order
  • The collection is small
  • You only need to check membership occasionally

Practical Example

// Scenario: Checking for banned usernames

// Array approach (slower for large lists)
const bannedUsernamesArray = ['admin', 'root', 'moderator', ...500MoreItems];
function isBannedArray(username) {
  return bannedUsernamesArray.includes(username);
}

// Set approach (faster)
const bannedUsernamesSet = new Set(['admin', 'root', 'moderator', ...500MoreItems]);
function isBannedSet(username) {
  return bannedUsernamesSet.has(username);
}

// The Set version will be much faster for repeated checks
Enter fullscreen mode Exit fullscreen mode

Memory Considerations

While Sets offer faster lookups, they typically consume about 20-30% more memory than arrays due to their internal hash table implementation. This tradeoff is usually worth it for performance-critical operations but might matter in memory-constrained environments.

Conversion Costs

If you frequently need to convert between arrays and Sets, consider the overhead:

// One-time conversion is fine
const mySet = new Set(largeArray);

// Repeated conversions are expensive
function inefficientCheck(arr, value) {
  return new Set(arr).has(value); // Creates new Set each time
}
Enter fullscreen mode Exit fullscreen mode

Browser Compatibility

Both methods are well-supported in modern browsers:

  • Array.includes(): ES2016+
  • Set.has(): ES2015+

For legacy environments, you'll need polyfills for both.

Conclusion

Set.has() is generally the better choice for membership testing in large collections or when performance is critical, while Array.includes() is more appropriate for small collections or when working with arrays that need to maintain their array-like characteristics. Understanding these differences allows you to make informed decisions that can significantly impact your application's performance.

Top comments (0)