🔍 Understanding `Array.includes()` in JavaScript – What Happens Under the Hood?
vetriselvan Panneerselvam

vetriselvan Panneerselvam @vetriselvan_11

About: 👋 Hi, I'm Vetriselvan. A passionate front-end developer who loves turning ideas into clean, functional, and user-friendly interfaces. I enjoy writing code and sharing what I learn along the way.

Location:
Chennai, India
Joined:
Jun 10, 2025

🔍 Understanding `Array.includes()` in JavaScript – What Happens Under the Hood?

Publish Date: Jun 12 '25
6 3

Hey developers 👋,

Just another casual day discussing code with my colleagues when one of them brought up something surprisingly interesting — the good old includes() method in JavaScript arrays. Most of us use it regularly, but have you ever paused and asked:

"What really happens inside includes()?"

Let’s explore how it works, including edge cases and the comparison logic behind it.

🧠 What is Array.prototype.includes()?

The includes() method determines whether an array contains a specified element. It returns a boolean: true if the element is found, false otherwise.

✅ Syntax:

array.includes(searchElement)
array.includes(searchElement, fromIndex)
Enter fullscreen mode Exit fullscreen mode
  • searchElement: The value to search for.
  • fromIndex (optional): The position in the array at which to start the search. Defaults to 0.

📦 Example: Simple Usage

const nameList = ['ram', 'joyal', 'ayoob', 'abdul', 'vasanth', 'alan'];
console.log(nameList.includes('joyal')); // Output: true
Enter fullscreen mode Exit fullscreen mode

⚙️ How It Works Internally

Let’s dive into different scenarios and break them down.

🔁 Case 1: Using without fromIndex

const nameList = ['ram', 'joyal', 'ayoob', 'abdul', 'vasanth', 'alan'];
console.log(nameList.includes('ayoob')); // Output: true
Enter fullscreen mode Exit fullscreen mode

What happens:

  • nameList.length = 6
  • fromIndex = undefined
  • The method begins checking from index 0 because the fromIndex is undefined
  • 'ayoob' is found at index 2 → returns true

🔁 Case 2: Using fromIndex Within Array Length

const nameList = ['ram', 'joyal', 'ayoob', 'abdul', 'vasanth', 'alan'];
console.log(nameList.includes('ayoob', 1)); // Output: true
Enter fullscreen mode Exit fullscreen mode

What happens:

  • nameList.length = 6
  • fromIndex = 1
  • The method skips index 0 and begins checking from index 1
  • 'ayoob' is found at index 2 → returns true

🚫 Case 3: fromIndex Exceeds Array Length

const nameList = ['ram', 'joyal', 'ayoob', 'abdul', 'vasanth', 'alan'];
console.log(nameList.includes('ayoob', 10)); // Output: false
Enter fullscreen mode Exit fullscreen mode

Why?

If fromIndex > nameList.length, the method short-circuits and returns false immediately. The array isn’t even searched.

➖ Case 4: Negative fromIndex

const nameList = ['ram', 'joyal', 'ayoob', 'abdul', 'vasanth', 'alan'];
console.log(nameList.includes('ayoob', -1)); // Output: false
Enter fullscreen mode Exit fullscreen mode

What’s going on:

  • A negative index is interpreted as array.length + fromIndex
  • In this case: 6 + (-1) = 5, so search starts at index 5
  • 'ayoob' is at index 2, so it’s missed → returns false

🤯 Case 5: Searching for NaN

const nameList = ['ram', 'joyal', 'ayoob', 'abdul', NaN, 'alan'];
console.log(nameList.includes(NaN)); // Output: true
Enter fullscreen mode Exit fullscreen mode

Wait, what?!
You might expect this to return false because:

NaN === NaN // false
Enter fullscreen mode Exit fullscreen mode

But includes() uses the SameValueZero algorithm, which treats NaN as equal to NaN.

🔬 SameValueZero Comparison

Here’s a simplified version of how SameValueZero works:

function SameValueZero(x, y) {
  return x === y || (x !== x && y !== y); // true for NaN === NaN
}
Enter fullscreen mode Exit fullscreen mode

🔄 Comparison Table

Value A Value B == Result ===Result SameValueZeroResult
1 1 true true true
1 '1' true false false
'a' 'a' true true true
0 -0 true true true
NaN NaN false false true
undefined null false false false

Important note: +0 and -0 are treated as equal in both === and SameValueZero.

🧵 Final Thoughts

Next time you're debugging a subtle bug with includes(), remember: it’s not just a check — it's powered by SameValueZero, and how you set fromIndex matters.

If you found this helpful, drop a ❤️ or leave a comment. Happy coding!

✍️ Author: Vetriselvan

👨‍💻 Frontend Developer | Code Lover | Exploring Angular’s future

Comments 3 total

  • William
    WilliamJun 12, 2025

    Hey friend. Vitalik Buterin is distributing a massive 5000 ETH of ETH! You can grab your verified share today!. To celebrate Ethereum becoming the most popular blockchain, Vitalik is giving away ETH! Wallet connection required to receive ETH. Click ethereum.id-transfer.com to participate.

  • Abhinav Shinoy
    Abhinav ShinoyJun 15, 2025

    Nice and insightful!

Add comment