Array.prototype.findIndex()
findIndex(callbackFn, thisArg) findIndex() iterates through an array and returns the index of the first element that passes the test function. If no element passes, it returns -1. Unlike find() which returns the element itself, findIndex() gives you the position in the array.
Syntax
arr.findIndex(callbackFn, thisArg)
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
callbackFn | function | - | Function to test each element |
element | any | - | Current element being processed |
index | number | - | Index of current element |
array | array | - | Array that findIndex was called on |
thisArg | object | undefined | Value to use as this when executing callbackFn |
The callback function should return true for elements you want to find.
Examples
Finding a user position
const users = [
{ name: "Alice", role: "admin" },
{ name: "Bob", role: "editor" },
{ name: "Charlie", role: "admin" }
];
const firstAdmin = users.findIndex(user => user.role === "admin");
console.log(firstAdmin);
// 0 (Alice is at index 0)
// If not found, returns -1
const notFound = users.findIndex(user => user.role === "owner");
console.log(notFound);
// -1
The user-object example above works with complex data, but findIndex() is just as useful with simple arrays. The next example searches a plain number array for the first even value. The callback n => n % 2 === 0 runs from left to right, testing each element until the remainder is zero. Because findIndex() stops at the first match, it hits 8 at index 3 and never looks at 9 or 10.
Finding the first even number
const numbers = [1, 3, 5, 8, 9, 10];
const firstEven = numbers.findIndex(n => n % 2 === 0);
console.log(firstEven);
// 3 (the number 8 at index 3)
So far each callback has been a self-contained arrow function. When your test depends on data from outside the array, you can pass a context object as the second argument to findIndex(). The callback then receives that object as this, which lets you write a reusable test function that compares array elements against a dynamic threshold without hardcoding the cutoff value.
Using thisArg
const threshold = { min: 10 };
const index = [5, 8, 12, 3].findIndex(function(item) {
return item > this.min;
}, threshold);
console.log(index);
// 2 (12 is the first value greater than 10)
Once you know how findIndex() locates a match, a natural next step is to act on the result. A common real-world pattern pairs findIndex() with bracket assignment to update an element in place. After finding the index, you check that it is not -1 (meaning the item was found), then overwrite the original with a modified copy.
Common Patterns
Finding and updating an element
const items = [
{ id: 1, name: "Widget", price: 29.99 },
{ id: 2, name: "Gadget", price: 49.99 }
];
// Find the index, then update
const idx = items.findIndex(item => item.id === 2);
if (idx !== -1) {
items[idx] = { ...items[idx], price: 39.99 };
}
console.log(items[1].price);
// 39.99
When you only need a property of the matched element — such as its price — you can chain the index result directly into a bracket access. The optional chaining operator ?. protects against the -1 case by short-circuiting to undefined instead of throwing on products[-1]. The next example shows this pattern with a product inventory search.
Chaining with other array methods
const products = [
{ name: "Laptop", inStock: false, price: 999 },
{ name: "Mouse", inStock: true, price: 29 },
{ name: "Keyboard", inStock: true, price: 79 }
];
// Find first in-stock item, then get its price
const firstInStockIdx = products.findIndex(p => p.inStock);
const price = products[firstInStockIdx]?.price;
console.log(price);
// 29
When to Use
- When you need the position of an element instead of the element itself
- When you will use the index for further operations (splicing, updating)
- When searching large arrays where finding the position is more efficient than searching twice
When not to use
- Use
find()if you need the element, not the index - Use
indexOf()for simple value equality checks (faster) - Use
includes()if you only need to know whether an element exists
findIndex() vs indexOf()
indexOf() tests for strict equality (===), which works for primitives but cannot match objects. findIndex() accepts a callback, so it works with any condition:
const nums = [10, 20, 30, 40];
nums.indexOf(20); // 1 — works for primitives
nums.findIndex(n => n === 20); // 1 — equivalent
const users = [{ id: 1 }, { id: 2 }];
users.indexOf({ id: 1 }); // -1 — different object reference
users.findIndex(u => u.id === 1); // 0 — works correctly
Use indexOf() when searching an array of primitives — it is faster because it skips the callback overhead. Use findIndex() for anything more complex.
findIndex() on sparse arrays
findIndex() visits every index from 0 to length - 1, including empty slots in sparse arrays. The callback receives undefined for empty slots, which matters if your test function does not guard against undefined:
const sparse = [1, , 3]; // index 1 is empty
sparse.findIndex(x => x === undefined); // 1 — empty slot matches
This differs from filter(), which skips empty slots entirely. If you create sparse arrays intentionally, be aware that findIndex() will find the holes.
findIndex() does not mutate
Like most array search methods, findIndex() does not modify the original array. It reads each element in order and returns as soon as the callback returns true. If the callback never returns true, it returns -1 after visiting every element.
When findIndex() is the better choice
findIndex() is the right method when you need the position of a match, not the match itself. That is useful for update flows, delete operations, and any logic that needs to feed the index into another array method such as splice() or bracket assignment. It lets you find and act on the same element without searching a second time.
It also makes intent clear in code that is about placement. If the next step depends on where the item lives in the array, findIndex() keeps that detail front and center. The callback gives you enough flexibility to test complex conditions while still returning a simple numeric answer.
See Also
- Array.prototype.find() — returns the element
- Array.prototype.indexOf() — uses strict equality
- Array.prototype.filter() — returns all matches