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
Top comments (2)
Nice and insightful!
Thanks for your feedback
Some comments may only be visible to logged-in visitors. Sign in to view all comments.