Array.prototype.indexOf()
Strict equality throughout, which has one famous consequence: an array containing NaN still reports -1 when you search for NaN.
Demo
The first matching index comes back, or -1 when there is no match. With duplicates you always get the earliest. The -1 is the part to be careful with: it is a perfectly ordinary number and it is TRUTHY, so testing the result without comparing it explicitly gives the opposite of what you meant for an element at index 0.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| searchElement | any | yes | Value to locate, compared with strict equality (===). |
| fromIndex | number | no (0) | Index to start from. Negative counts from the end. Past the length returns -1 immediately. |
Return value
number — Index of the first strictly-equal element, or -1 if there is none. NaN is never found, because NaN !== NaN.
Common patterns
const i = items.indexOf(value); if (i !== -1) items.splice(i, 1);
if (items.includes(value)) { ... }
let i = items.indexOf(v); while (i !== -1) { found.push(i); i = items.indexOf(v, i + 1); }
Examples
Pitfalls
if (items.indexOf(x)) { /* "found" */ }
if (items.indexOf(x) !== -1) { ... }
[NaN].indexOf(NaN)
[NaN].includes(NaN)
[1, 2, 3].indexOf('2')
[1, 2, 3].indexOf(Number("2"))
[{id: 1}].indexOf({id: 1})
[{id: 1}].findIndex(o => o.id === 1)
When to use
- You need the POSITION of a value
- Find-then-splice removal by value
- Walking every occurrence with fromIndex
- You only need presence → includes, which reads better
- The value might be NaN → includes
- Matching objects by contents → findIndex
Notes
FAQ
Because it compares with strict equality, and NaN === NaN is false by IEEE-754 definition. No strict-equality search can ever match NaN. includes uses SameValueZero instead, which treats NaN as equal to itself.
[NaN].indexOf(NaN) // -1 [NaN].includes(NaN) // true