JavaScript includes() vs indexOf() - Element Existence Checks
Compare Array.includes() and indexOf() for checking element existence. Covers NaN handling, fromIndex, and when to use Set instead. Free reference.
Detailed Explanation
includes() vs indexOf()
Both methods check whether an array contains a specific value, but they differ in return type and NaN handling.
Array.includes()
Returns a boolean — simple and clear:
const fruits = ["apple", "banana", "cherry"];
fruits.includes("banana"); // true
fruits.includes("grape"); // false
Array.indexOf()
Returns the index of the first occurrence, or -1 if not found:
const fruits = ["apple", "banana", "cherry"];
fruits.indexOf("banana"); // 1
fruits.indexOf("grape"); // -1
Key Difference: NaN Handling
const arr = [1, 2, NaN, 4];
arr.includes(NaN); // true ✓
arr.indexOf(NaN); // -1 ✗ (cannot find NaN!)
includes() uses the SameValueZero algorithm, which correctly identifies NaN. indexOf() uses strict equality (===), and since NaN !== NaN, it cannot find NaN values.
fromIndex Parameter
Both support a second argument to start searching from a specific index:
const arr = ["a", "b", "c", "a", "b"];
arr.includes("a", 2); // true (finds the second "a")
arr.indexOf("a", 2); // 3 (index of second "a")
When to Use Which
| Scenario | Use |
|---|---|
| Just need true/false | includes() |
| Need the position | indexOf() |
| Array may contain NaN | includes() |
| Need custom condition | find() or findIndex() |
Performance: When to Use Set
For frequent lookups on large arrays, convert to a Set first:
// O(n) per lookup
array.includes(value);
// O(1) per lookup after O(n) setup
const set = new Set(array);
set.has(value);
If you are checking membership in a loop, a Set is significantly faster for arrays larger than ~100 elements.
Use Case
Use includes() as the default for simple membership checks (checking permissions, validating input against allowed values). Use indexOf() only when you need the element's position. Switch to a Set for performance-critical code with many lookups.