Array.prototype.entries()
Returns an iterator of [index, element] pairs, one for each position in the array.
entries()- Added in JavaScript ECMAScript 2015
Return value
Array IteratorA new iterable iterator object yielding a two-element [index, element] array for each index.
Errors
Throws a TypeError only if called on null or undefined.
entries() yields [index, element] pairs, which makes it the clean way to run a for...of loop that needs the position as well as the value. Destructure in the loop head and both are named:
for (const [i, item] of list.entries()) { … }When to reach for it
Use it instead of forEach((item, i) => …) whenever the body needs break, continue, return, or await — none of which work meaningfully inside a forEach callback. It also pairs with Object.fromEntries() to turn a list into an index-keyed object.
What trips people up
- Each iteration allocates a fresh two-element array. That is irrelevant for ordinary loops but noticeable in a hot path over millions of items, where a counting
forloop is cheaper. - The iterator is single-use, like all array iterators.
- Holes in a sparse array are yielded as
[i, undefined]rather than skipped. - It is unrelated to
Object.entries(), which returns an array of string-keyed pairs and skips empty slots.
Example
When to use it
- Print a numbered list where the body may break early.
- Await something per item inside a for...of loop that also needs the index.
- Find the index of the first element matching a multi-step condition.
- Build an index-keyed object with Object.fromEntries(list.entries()).
Frequently asked questions
How do I get the index in a for...of loop?
Iterate arr.entries() and destructure the pair: for (const [i, value] of arr.entries()). Each step yields a two-element array holding the index and the element.
Should I use entries() or forEach() with an index?
Use entries() when the loop body needs break, continue, return, or await, since none of those work inside a forEach callback. forEach() is fine for a straightforward pass with no early exit.
Is Array.prototype.entries() the same as Object.entries()?
No. Array.prototype.entries() returns a single-use iterator of [numericIndex, value] pairs covering every position including holes, while Object.entries() returns a plain array of [stringKey, value] pairs and skips empty slots.
More examples
break and await, which forEach cannot do
The loop awaits each job in sequence and stops after index 1. Inside a forEach callback, break is a syntax error and await would not pause the outer function.
const jobs = ["a", "b", "c", "d"];
for (const [i, job] of jobs.entries()) {
const result = await Promise.resolve(job.toUpperCase());
console.log(i, result);
if (i === 1) break;
}
console.log("stopped early");Sparse arrays and Object.entries()
entries() reports index 1 with an undefined value, Object.entries() omits it entirely, and forEach() skips it too. Only entries() gives you a pair for every position.
const sparse = ["a", , "c"];
console.log([...sparse.entries()]);
console.log(Object.entries(sparse));
sparse.forEach((v, i) => console.log("forEach saw", i, v));Comparing adjacent elements
Having the index in scope lets the body reach back to the previous element. continue skips the first reading, which has nothing to compare against.
const readings = [3, 5, 5, 2, 9];
for (const [i, value] of readings.entries()) {
if (i === 0) continue;
const delta = value - readings[i - 1];
console.log(`${i}: ${value} (${delta >= 0 ? "+" : ""}${delta})`);
}
Discussion