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)
-
searchElement: The value to search for. -
fromIndex(optional): The position in the array at which to start the search. Defaults to0.
📦 Example: Simple Usage
const nameList = ['ram', 'joyal', 'ayoob', 'abdul', 'vasanth', 'alan'];
console.log(nameList.includes('joyal')); // Output: true
⚙️ 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
What happens:
nameList.length = 6fromIndex = undefined- The method begins checking from index
0because the fromIndex is undefined -
'ayoob'is found at index2→ returnstrue
🔁 Case 2: Using fromIndex Within Array Length
const nameList = ['ram', 'joyal', 'ayoob', 'abdul', 'vasanth', 'alan'];
console.log(nameList.includes('ayoob', 1)); // Output: true
What happens:
nameList.length = 6fromIndex = 1- The method skips index
0and begins checking from index1 -
'ayoob'is found at index2→ returnstrue
🚫 Case 3: fromIndex Exceeds Array Length
const nameList = ['ram', 'joyal', 'ayoob', 'abdul', 'vasanth', 'alan'];
console.log(nameList.includes('ayoob', 10)); // Output: false
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
What’s going on:
- A negative index is interpreted as
array.length + fromIndex - In this case:
6 + (-1) = 5, so search starts at index5 -
'ayoob'is at index2, so it’s missed → returnsfalse
🤯 Case 5: Searching for NaN
const nameList = ['ram', 'joyal', 'ayoob', 'abdul', NaN, 'alan'];
console.log(nameList.includes(NaN)); // Output: true
Wait, what?!
You might expect this to return false because:
NaN === NaN // false
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
}
🔄 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





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.