entries
Sometimes you need both pieces of information while looping through an array:
- the index
- the value at that index
You already know arrays are zero-indexed:
const fruits = ["Apple", "Banana", "Cherry"];
console.log(fruits[0]); // Apple
console.log(fruits[1]); // Banana
console.log(fruits[2]); // CherryThe .entries() method gives you a clean way to loop over both the index and the value together.
What Is entries?
The .entries() method returns an iterator containing index-value pairs from an array.
Each pair looks like this:
[index, value]Example:
const fruits = ["Apple", "Banana", "Cherry"];
const entries = fruits.entries();
console.log(entries);The result is an iterator object.
You usually do not use that object directly.
Instead, you loop over it.
Basic Example With for...of
The most common way to use .entries() is with for...of.
const fruits = ["Apple", "Banana", "Cherry"];
for (const entry of fruits.entries()) {
console.log(entry);
}Output:
[0, "Apple"]
[1, "Banana"]
[2, "Cherry"]Each entry is an array with two values:
- the index
- the element
Using Destructuring
Because each entry is an array, you can use destructuring.
const fruits = ["Apple", "Banana", "Cherry"];
for (const [index, fruit] of fruits.entries()) {
console.log(`${index}: ${fruit}`);
}Output:
0: Apple
1: Banana
2: CherryThis is the cleanest way to use .entries().
The destructuring:
const [index, fruit]takes the two values from each entry array.
Why Use entries?
Use .entries() when you want the readability of for...of, but you also need the index.
Without entries, you might write a traditional for loop:
const fruits = ["Apple", "Banana", "Cherry"];
for (let index = 0; index < fruits.length; index++) {
console.log(`${index}: ${fruits[index]}`);
}This works, but it is more mechanical.
With .entries():
for (const [index, fruit] of fruits.entries()) {
console.log(`${index}: ${fruit}`);
}This reads more directly:
For each index-value pair in the array, do something.Human-Friendly Numbering
Indexes start at 0, but users usually expect numbering to start at 1.
const steps = ["Install", "Build", "Deploy"];
for (const [index, step] of steps.entries()) {
console.log(`${index + 1}. ${step}`);
}Output:
1. Install
2. Build
3. DeployThis is a common use case for .entries().
You use the real index for calculations, then display index + 1.
Practical Example: Rendering Labels
Imagine you want to create labels for a list of tasks.
const tasks = ["Write notes", "Review lesson", "Publish update"];
const labels = [];
for (const [index, task] of tasks.entries()) {
labels.push(`Task ${index + 1}: ${task}`);
}
console.log(labels);Output:
[
"Task 1: Write notes",
"Task 2: Review lesson",
"Task 3: Publish update"
]This could also be done with .map(), but .entries() is useful when you prefer loop syntax.
Practical Example: Finding Positions While Looping
You can use .entries() when the index matters during a loop.
const scores = [80, 95, 72, 88];
for (const [index, score] of scores.entries()) {
if (score < 75) {
console.log(`Score at index ${index} needs review.`);
}
}Output:
Score at index 2 needs review.The value tells you what happened.
The index tells you where it happened.
entries Returns an Iterator
.entries() does not return a normal array.
It returns an iterator.
const fruits = ["Apple", "Banana"];
const iterator = fruits.entries();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());Output:
{ value: [0, "Apple"], done: false }
{ value: [1, "Banana"], done: false }
{ value: undefined, done: true }An iterator produces values one at a time.
Most of the time, you do not call .next() manually.
You use for...of instead:
for (const [index, fruit] of fruits.entries()) {
console.log(index, fruit);
}Converting Entries to an Array
If you want to see all entries as a normal array, use Array.from().
const fruits = ["Apple", "Banana", "Cherry"];
const entryArray = Array.from(fruits.entries());
console.log(entryArray);Output:
[
[0, "Apple"],
[1, "Banana"],
[2, "Cherry"]
]You can also use spread syntax:
const entryArray = [...fruits.entries()];Both produce an array of index-value pairs.
entries vs forEach
forEach also gives you the current value and index.
const fruits = ["Apple", "Banana", "Cherry"];
fruits.forEach((fruit, index) => {
console.log(`${index}: ${fruit}`);
});So why use .entries()?
.entries() works nicely with for...of.
That gives you loop control tools like break and continue.
for (const [index, fruit] of fruits.entries()) {
if (fruit === "Banana") {
break;
}
console.log(`${index}: ${fruit}`);
}You cannot use break inside forEach.
So .entries() plus for...of is useful when you need both:
- index-value pairs
- loop control
entries vs keys vs values
Arrays also have .keys() and .values().
const fruits = ["Apple", "Banana", "Cherry"];.keys() gives indexes:
for (const index of fruits.keys()) {
console.log(index);
}Output:
0
1
2.values() gives values:
for (const fruit of fruits.values()) {
console.log(fruit);
}Output:
Apple
Banana
Cherry.entries() gives both:
for (const [index, fruit] of fruits.entries()) {
console.log(index, fruit);
}Output:
0 Apple
1 Banana
2 CherryComparison Table
| Method | Gives you | Example item |
|---|---|---|
keys() |
Indexes | 0 |
values() |
Values | "Apple" |
entries() |
Index-value pairs | [0, "Apple"] |
Use the method that gives you the data you need.
If you only need values, a plain for...of is often enough:
for (const fruit of fruits) {
console.log(fruit);
}If you need both index and value, use .entries().
Modifying Values While Using entries
You can use the index from .entries() to update array elements.
const numbers = [1, 2, 3];
for (const [index, number] of numbers.entries()) {
numbers[index] = number * 2;
}
console.log(numbers); // [2, 4, 6]This mutates the original array.
If you want a new transformed array, use .map() instead:
const doubled = numbers.map((number) => number * 2);Use .entries() for index-aware looping.
Use .map() for transformations.
Skipping Items With continue
Because .entries() is often used with for...of, you can use continue.
const scores = [90, 40, 75, 30];
for (const [index, score] of scores.entries()) {
if (score >= 50) {
continue;
}
console.log(`Score at index ${index} failed.`);
}Output:
Score at index 1 failed.
Score at index 3 failed.This is harder to express cleanly with forEach because continue is not allowed inside a forEach callback.
Stopping Early With break
You can also stop early.
const users = ["Ava", "Noah", "Mira", "Liam"];
for (const [index, user] of users.entries()) {
if (user === "Mira") {
console.log(`Found Mira at index ${index}`);
break;
}
}Output:
Found Mira at index 2If your goal is simply to find an item, .find() or .findIndex() may be clearer.
But .entries() is useful when you are doing custom loop logic.
Entries and Sparse Arrays
Sparse arrays have empty slots.
const values = [];
values[2] = "Hello";This creates empty slots at indexes 0 and 1.
With .entries():
for (const [index, value] of values.entries()) {
console.log(index, value);
}Output:
0 undefined
1 undefined
2 HelloThis is another reason to avoid sparse arrays when possible.
Use normal methods like push() to build arrays.
Best Practices
Use .entries() when you need both index and value:
for (const [index, item] of items.entries()) {
console.log(index, item);
}Use destructuring for readability:
for (const [index, task] of tasks.entries()) {
console.log(`${index + 1}. ${task}`);
}Use for...of with .entries() when you need break or continue:
for (const [index, value] of values.entries()) {
if (value == null) {
continue;
}
console.log(index, value);
}Use .map() if your goal is to create a transformed array:
const labels = tasks.map((task, index) => `${index + 1}. ${task}`);Use .findIndex() if your goal is only to find an index:
const index = users.findIndex((user) => user.id === targetId);Common Mistakes
Mistake 1: Expecting entries() to Return a Normal Array
const fruits = ["Apple", "Banana"];
const entries = fruits.entries();
console.log(entries[0]); // undefinedentries() returns an iterator, not a normal array.
Convert it if needed:
const entriesArray = [...fruits.entries()];
console.log(entriesArray[0]); // [0, "Apple"]Mistake 2: Forgetting Destructuring
const fruits = ["Apple", "Banana"];
for (const entry of fruits.entries()) {
console.log(entry);
}This logs arrays like:
[0, "Apple"]
[1, "Banana"]That is fine, but destructuring is usually clearer:
for (const [index, fruit] of fruits.entries()) {
console.log(index, fruit);
}Mistake 3: Using entries() When You Only Need Values
for (const [index, fruit] of fruits.entries()) {
console.log(fruit);
}If you do not need the index, write:
for (const fruit of fruits) {
console.log(fruit);
}Mistake 4: Using entries() Instead of map() for Transformations
const labels = [];
for (const [index, task] of tasks.entries()) {
labels.push(`${index + 1}. ${task}`);
}This works.
But if your goal is only to create a new array, .map() is often clearer:
const labels = tasks.map((task, index) => `${index + 1}. ${task}`);Quick Check
What does this log?
const colors = ["Red", "Green"];
for (const entry of colors.entries()) {
console.log(entry);
}It logs:
[0, "Red"]
[1, "Green"]What does this log?
const colors = ["Red", "Green"];
for (const [index, color] of colors.entries()) {
console.log(`${index}: ${color}`);
}It logs:
0: Red
1: GreenHow do you convert entries to a normal array?
Use spread syntax:
const entriesArray = [...colors.entries()];Or use Array.from():
const entriesArray = Array.from(colors.entries());Summary
entries() gives you index-value pairs from an array.
- Each entry is
[index, value]. entries()returns an iterator, not a normal array.- Use
for...ofto loop over entries. - Use destructuring like
[index, value]for readability. - Use
entries()when you need both the index and the value. - Use
keys()when you only need indexes. - Use
values()or plainfor...ofwhen you only need values. - Use
map()when your goal is to create a transformed array. - Use
findIndex()when your goal is only to find an index.