Array.prototype.indexOf()

Returns the first index at which a value is found, or -1 if it is absent.

Signature
indexOf(searchElement)
indexOf(searchElement, fromIndex)
  • Added in JavaScript ES5 (2009)

Parameters

ParameterTypeDescription
$searchElementanyThe value to locate, compared using strict equality (===).
$fromIndexoptionalinteger= 0Zero-based index to start searching at, converted to an integer. A negative value counts back from the end (fromIndex + array.length); below -array.length it is treated as 0. If it is at least array.length, -1 is returned without searching.

Return value

numberThe first index at which searchElement is found, or -1 if it is not present.

indexOf() scans forward from fromIndex and returns the position of the first element strictly equal to searchElement, or -1. It compares with ===: no type coercion, and object elements match only by reference.

When to reach for it

Use it when you need the index of a primitive — to splice() it out, to overwrite it, or to slice around it. If all you want is a yes/no answer, includes() reads better and avoids the sentinel. If you need to match on a property rather than a value, use findIndex().

What trips people up

NaN is unfindable. Strict equality says NaN !== NaN, so [NaN].indexOf(NaN) is -1 even though the value is right there. includes() or findIndex(Number.isNaN) will find it.

-1 is truthy, so if (arr.indexOf(x)) is wrong in both directions — it is falsy for a hit at index 0 and truthy for a miss. Always write !== -1.

Empty slots in sparse arrays are skipped entirely, so [1, , 3].indexOf(undefined) is -1 while includes(undefined) is true.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Get the position of a value so you can splice it out
  • Collect every occurrence of a value by looping with fromIndex
  • Deduplicate an array by keeping only first occurrences
  • Find where a delimiter first appears in a token list

Frequently asked questions

Why does indexOf() return -1 for a value I can see in the array?

Three usual causes: the value is NaN, which strict equality can never match; the types differ, such as '2' versus 2; or the element is an object and you passed a structurally identical but different object. Use includes(), normalise the type, or use findIndex() with a predicate.

Should I use indexOf() or includes() to check existence?

Use includes() — it returns a boolean, so there is no -1 to forget, and it correctly finds NaN. Keep indexOf() for when you actually need the position.

How do I find all indexes of a value, not just the first?

Loop with the fromIndex argument, restarting at pos + 1 until indexOf returns -1. Alternatively use reduce() or flatMap() with the index argument to collect matching positions in one pass.

More examples

Collecting every occurrence with fromIndex

Prints [0, 2, 3]. Each pass restarts the search one slot past the previous hit; the loop ends when indexOf returns -1. Forgetting the + 1 would find index 0 forever.

Example · javascript
const seq = [4, 9, 4, 4, 1];
const hits = [];

let pos = seq.indexOf(4);
while (pos !== -1) {
  hits.push(pos);
  pos = seq.indexOf(4, pos + 1);
}

console.log(hits);

Strict equality, NaN and sparse holes

Prints -1; then -1 and true; then -1 and true. The string '2' is not coerced to a number, NaN never equals itself under ===, and indexOf skips the empty slot that includes() reports as undefined.

Example · javascript
console.log([1, 2, 3].indexOf("2"));
console.log([NaN].indexOf(NaN), [NaN].includes(NaN));
console.log([1, , 3].indexOf(undefined), [1, , 3].includes(undefined));

Discussion

  • Be the first to comment on this lesson.