Last modified: Aug 03, 2026

Array includes() vs indexOf() in JS

When working with arrays in JavaScript, you often need to check if a value exists. Two popular methods for this are includes() and indexOf().

They might seem similar at first glance. But they have important differences. Understanding these will help you write cleaner and more predictable code.

This guide breaks down both methods. You will learn their syntax, behavior, and use cases. By the end, you'll know exactly which one to choose for your next project.

What is the includes() Method?

The includes() method checks if an array contains a certain value. It returns a boolean: true if the value exists, and false if it doesn't.

This method is perfect for simple existence checks. You don't need the position of the item. You just want to know if it's there.

Here is a basic example:


// Basic includes() example
const fruits = ['apple', 'banana', 'mango'];

console.log(fruits.includes('banana')); // true
console.log(fruits.includes('grape'));  // false

The syntax is straightforward. You call includes() on the array. You pass the value you want to search for as an argument.

It also accepts an optional second parameter. This is the starting index for the search. This is useful when you want to search a specific part of the array.

What is the indexOf() Method?

The indexOf() method also searches for a value in an array. But it returns the first index where the value is found. If the value is not found, it returns -1.

This method is older and was the standard way to check for existence before includes() was introduced. Developers would check if the result was not equal to -1.

Here is a basic example:


// Basic indexOf() example
const fruits = ['apple', 'banana', 'mango'];

console.log(fruits.indexOf('banana')); // 1
console.log(fruits.indexOf('grape'));  // -1

The key difference is that indexOf() gives you more information. It tells you the exact position of the element. This can be very useful for other operations.

For example, you might need the index to remove an element or to access its neighbors in the array.

Key Differences: includes() vs indexOf()

The most significant difference is in their return values. includes() returns a boolean. indexOf() returns a number.

This affects how you write your conditionals. With includes(), you write an if statement directly. With indexOf(), you need to compare the result to -1.

Let's compare the code style:


// Using includes() - clean and direct
const hasBanana = fruits.includes('banana');
if (hasBanana) {
  console.log('We have a banana!');
}

// Using indexOf() - requires comparison
const bananaIndex = fruits.indexOf('banana');
if (bananaIndex !== -1) {
  console.log('We have a banana!');
}

As you can see, includes() leads to more readable code. The intention is clear. You are simply checking for existence.

With indexOf(), you must remember that -1 means "not found". This is a common source of bugs for beginners.

Handling NaN: A Critical Difference

Here is where the two methods really diverge. The includes() method uses the SameValueZero algorithm for comparison. This means it can find NaN in an array.

The indexOf() method uses strict equality (===). Strict equality considers NaN to be different from itself. So indexOf() will never find NaN.

This is a huge advantage for includes(). Let's see it in action:


// NaN handling difference
const numbers = [1, 2, NaN, 4];

// includes() can find NaN
console.log(numbers.includes(NaN)); // true

// indexOf() cannot find NaN
console.log(numbers.indexOf(NaN)); // -1

In this example, includes() correctly returns true. But indexOf() returns -1, even though NaN is clearly in the array.

If you need to check for NaN, includes() is your only choice between these two methods. This alone makes it the better option in many cases.

Checking for -1 and 0

Another subtle difference involves the value 0 and -0. Both methods treat 0 and -0 as the same value. So this is not a differentiator.

However, there is a common pitfall with indexOf(). If the element you are looking for is at index 0, the method returns 0. In a boolean context, 0 is falsy.

This can cause issues if you write a condition like this:


// The pitfall with indexOf() and 0
const myArray = ['first', 'second'];

// This condition will NOT work as expected
if (myArray.indexOf('first')) {
  console.log('Found first element!'); // This will NOT run
}

// Correct way
if (myArray.indexOf('first') !== -1) {
  console.log('Found first element!'); // This will run
}

In the first condition, indexOf('first') returns 0. Since 0 is falsy, the code inside the if block never executes. This is a classic bug.

Using includes() avoids this entirely. It always returns a boolean, which is much safer and more intuitive.

Performance Considerations

In most cases, the performance difference between includes() and indexOf() is negligible. Both methods have a time complexity of O(n). This means they might have to check every element in the array.

However, indexOf() can be slightly faster in some JavaScript engines. This is because it has been around longer and has more optimizations.

But for typical applications, this difference is not noticeable. You should prioritize readability and correctness over micro-optimizations.

If you are working with very large arrays and performance is critical, you should benchmark both methods. But for 99% of use cases, choose the one that makes your code clearer.

When to Use includes()

You should use includes() when you only need to know if a value exists. It is the modern and recommended approach for this task.

It is especially useful when you need to handle NaN. It also makes your code more readable and avoids the -1 comparison pitfall.

Here are some common use cases:


// Checking user permissions
const userRoles = ['admin', 'editor'];
if (userRoles.includes('admin')) {
  console.log('User has admin access.');
}

// Checking if an item is in a shopping cart
const cartItems = ['shirt', 'pants'];
if (cartItems.includes('shirt')) {
  console.log('Shirt is already in cart.');
}

In both examples, you just need a yes or no answer. includes() is perfect for this.

When to Use indexOf()

You should use indexOf() when you need the actual index of the element. This is necessary for tasks like removing an element or updating it.

For example, if you want to remove an item from an array, you need its index to use with splice().

Here is a practical example:


// Removing an element using indexOf()
const tasks = ['write code', 'debug', 'test'];
const taskToRemove = 'debug';

const index = tasks.indexOf(taskToRemove);
if (index !== -1) {
  tasks.splice(index, 1);
}

console.log(tasks); // ['write code', 'test']

In this case, includes() would not be helpful. You need the index to perform the removal. indexOf() provides that.

Remember, indexOf() returns the first occurrence. If you need all occurrences, you will need a loop.

Browser Support and Modern JavaScript

Both methods are well-supported in all modern browsers. indexOf() has been around since JavaScript 1.6. includes() is newer but is now universally supported.

If you are working with older environments, you might need to use indexOf(). But for any modern project, includes() is safe to use.

The JavaScript ecosystem is moving towards more expressive methods. includes() is part of this trend. It makes your code more semantic and easier to read.

For more on array methods, check out our JavaScript Array Methods Guide.

Practical Examples and Output

Let's look at a few more examples to solidify your understanding. We will compare the output of both methods.


// Comprehensive comparison
const mixedArray = [10, 20, 30, 40];

// Example 1: Finding an existing value
console.log(mixedArray.includes(20)); // true
console.log(mixedArray.indexOf(20));  // 1

// Example 2: Finding a non-existing value
console.log(mixedArray.includes(50)); // false
console.log(mixedArray.indexOf(50));  // -1

// Example 3: Using a starting index
console.log(mixedArray.includes(30, 2)); // true (starts at index 2)
console.log(mixedArray.indexOf(30, 2));  // 2

Notice how includes() gives a boolean. indexOf() gives a number. The starting index works the same for both.

Here is the output of the above code:


true
1
false
-1
true
2

This clearly shows the return type difference. This is the core concept to remember.

Working with Objects and References

Both methods compare by reference for objects. This means they check if the exact same object is in the array. They do not compare the contents of the objects.

This is an important distinction. Two objects with the same properties are not considered equal.


// Object reference comparison
const obj1 = { name: 'John' };
const obj2 = { name: 'John' };
const objArray = [obj1];

console.log(objArray.includes(obj2)); // false
console.log(objArray.indexOf(obj2));  // -1

console.log(objArray.includes(obj1)); // true
console.log(objArray.indexOf(obj1));  // 0

Even though obj1 and obj2 look the same, they are different objects in memory. So both methods fail to find obj2.

If you need to find an object by its properties, you need to use methods like find() or findIndex(). See our guide on JavaScript Array of Objects for more details.

Conclusion

Choosing between includes() and indexOf() depends on your specific need.

Use includes() for simple existence checks. It is more readable, handles NaN correctly, and avoids the -1 pitfall. It is the modern standard.

Use indexOf() when you need the actual index of the element. This is essential for operations like removing or replacing items in an array.

For a deeper dive into array manipulation, you might find our JavaScript Array Destructuring Guide helpful. Also, understanding how to convert arrays to strings is a useful skill.

Remember to prioritize code clarity. In most cases, includes() will be your best choice. It makes your intentions clear and your code less prone to bugs.