Array.prototype.entries, keys and values
All three return an iterator rather than an array, which is why logging one shows "Object [Array Iterator] {}" instead of your data. entries is the only one most code ever needs.
Demo
The demo spreads the iterator into an array so you can see what it yields — without the spread you would just get "Object [Array Iterator] {}". entries gives [index, value] pairs, keys gives the indices alone, and values gives the elements, which is what a plain for...of already does. That is why entries is the one worth remembering: it is the clean way to get the index alongside the element.
Common patterns
for (const [i, item] of items.entries()) { console.log(i, item); }
const indices = [...items.keys()];
const range = [...Array(5).keys()]; // [0, 1, 2, 3, 4]
Examples
Pitfalls
['a', 'b'].entries().length
[...['a', 'b'].entries()].length
const it = items.entries(); [...it]; [...it]
[...items.entries()]; [...items.entries()]
for (const x of items.values()) { ... }
for (const x of items) { ... }
Object.entries(['a'])
[...['a'].entries()]
When to use
- Getting the index alongside the element in for...of — use entries
- Producing a numeric range with [...Array(n).keys()]
- Manual step-by-step iteration with .next()
- Plain iteration over elements → for...of directly, not values()
- You want an array of pairs eagerly → Object.entries, or spread
- You need to iterate twice → call the method again, or store the spread
Notes
FAQ
Because it is an iterator, not an array — a lazy object that produces values on demand and has nothing to display until consumed. Spread it into an array or loop over it to see the contents.
console.log([...items.entries()]);