forEach
In the previous lesson, you learned how arrays store ordered collections of values.
Now you need a way to do something with each item in an array.
You could use a for loop:
const fruits = ["Apple", "Banana", "Cherry"];
for (let i = 0; i < fruits.length; i++) {
console.log(fruits[i]);
}This works, but it requires you to manage:
- the counter variable
- the loop condition
- the index lookup
JavaScript gives you a cleaner array method for this kind of task: forEach.
What Is forEach?
forEach is an array method that runs a callback function once for each element in an array.
const fruits = ["Apple", "Banana", "Cherry"];
fruits.forEach(function (fruit) {
console.log(fruit);
});Output:
Apple
Banana
CherryforEach is a higher-order function because it receives another function as an argument.
The function you pass to forEach is called a callback.
Basic Syntax
The general syntax looks like this:
array.forEach(function (currentValue, index, array) {
// code to run for each item
});The callback can receive three arguments:
| Argument | Meaning | Common? |
|---|---|---|
currentValue |
The current element being processed | Yes |
index |
The index of the current element | Sometimes |
array |
The original array forEach was called on |
Rarely |
Most of the time, you only need the first argument.
const names = ["Ava", "Noah", "Mira"];
names.forEach(function (name) {
console.log(name);
});How forEach Works
Think of forEach like this:
For each item in this array, run this callback.Example:
const numbers = [10, 20, 30];
numbers.forEach(function (number) {
console.log(number);
});JavaScript calls the callback three times:
// first call
callback(10);
// second call
callback(20);
// third call
callback(30);You do not write those calls manually.
forEach handles them for you.
Using an Anonymous Function
A common forEach pattern uses an anonymous function.
const fruits = ["Apple", "Banana", "Cherry"];
fruits.forEach(function (fruit) {
console.log(fruit);
});The callback function has no name because it is only used here.
This is readable when the callback is short.
Using an Arrow Function
Modern JavaScript often uses arrow functions with forEach.
const fruits = ["Apple", "Banana", "Cherry"];
fruits.forEach((fruit) => {
console.log(fruit);
});For a very short callback, you may see this concise form:
fruits.forEach((fruit) => console.log(fruit));All three versions do the same thing:
fruits.forEach(function (fruit) {
console.log(fruit);
});
fruits.forEach((fruit) => {
console.log(fruit);
});
fruits.forEach((fruit) => console.log(fruit));Use the style that is clearest for the amount of logic you have.
Using the Index
Sometimes you need to know the position of the current item.
The second callback argument is the index.
const colors = ["Red", "Green", "Blue"];
colors.forEach((color, index) => {
console.log(`Color #${index + 1} is ${color}`);
});Output:
Color #1 is Red
Color #2 is Green
Color #3 is BlueThe index starts at 0, so this expression:
index + 1is used to display human-friendly numbering.
Using the Original Array Argument
The third callback argument is the original array.
const scores = [80, 90, 100];
scores.forEach((score, index, array) => {
console.log(`${score} is item ${index + 1} of ${array.length}`);
});Output:
80 is item 1 of 3
90 is item 2 of 3
100 is item 3 of 3This third argument is available, but it is not used as often.
If you already have access to the array variable, you can usually use that directly:
scores.forEach((score, index) => {
console.log(`${score} is item ${index + 1} of ${scores.length}`);
});forEach Is Good for Side Effects
forEach is best when you want to perform a side effect for each item.
A side effect is an action that affects something outside the callback's returned value.
Common side effects include:
- logging to the console
- updating the page
- sending data somewhere
- pushing values into another array
- updating an object
Example:
const tasks = ["Write notes", "Review code", "Deploy app"];
tasks.forEach((task) => {
console.log(`Task: ${task}`);
});Here, the side effect is logging.
Practical Example: Building a Total
You can use forEach to update an outer variable.
const prices = [10, 20, 30];
let total = 0;
prices.forEach((price) => {
total += price;
});
console.log(total); // 60This works because the callback can access and update total.
However, later in this module you will learn that .reduce() is often a better fit for calculating a single value from an array.
For now, this example shows that forEach can perform repeated actions.
Practical Example: Updating the DOM
In browser code, forEach is often used to create or update elements.
const items = ["Home", "About", "Contact"];
const list = document.querySelector("#menu");
items.forEach((item) => {
const li = document.createElement("li");
li.textContent = item;
list.appendChild(li);
});The callback runs once for each menu item.
Each run creates and appends one <li> element.
This is a good use of forEach because the goal is a side effect: updating the page.
forEach Returns undefined
This is one of the most important rules.
forEach always returns undefined.
const numbers = [1, 2, 3];
const result = numbers.forEach((number) => {
return number * 2;
});
console.log(result); // undefinedThe return statement inside the callback does not make forEach return a new array.
It only returns from the current callback call.
If you want a new transformed array, use map.
const numbers = [1, 2, 3];
const doubled = numbers.map((number) => {
return number * 2;
});
console.log(doubled); // [2, 4, 6]You will learn map in the next lesson.
return Inside forEach
A return inside a forEach callback exits only that callback execution.
const numbers = [1, 2, 3, 4];
numbers.forEach((number) => {
if (number % 2 === 0) {
return;
}
console.log(number);
});Output:
1
3This return skips the rest of the callback for the current item.
It does not stop the whole forEach.
The callback still runs for the next item.
You Cannot break Out of forEach
forEach is not a loop statement.
It is a method call.
Because of that, you cannot use break inside it.
const numbers = [1, 2, 3, 4, 5];
numbers.forEach((number) => {
if (number === 3) {
break;
}
console.log(number);
});This causes a syntax error.
If you need to stop early, use a regular loop or a for...of loop.
const numbers = [1, 2, 3, 4, 5];
for (const number of numbers) {
if (number === 3) {
break;
}
console.log(number);
}Output:
1
2You Cannot continue in forEach
You also cannot use continue inside forEach.
numbers.forEach((number) => {
if (number % 2 === 0) {
continue;
}
console.log(number);
});This causes a syntax error.
Use return to skip the current callback:
const numbers = [1, 2, 3, 4];
numbers.forEach((number) => {
if (number % 2 === 0) {
return;
}
console.log(number);
});Output:
1
3This behaves like "skip this item," but it does not stop the entire iteration.
forEach vs for...of
Use forEach when you want to run a callback for every item.
const names = ["Ava", "Noah", "Mira"];
names.forEach((name) => {
console.log(name);
});Use for...of when you need loop control like break or continue.
const names = ["Ava", "Noah", "Mira"];
for (const name of names) {
if (name === "Noah") {
break;
}
console.log(name);
}Output:
Avafor...of gives you more control.
forEach gives you a clean callback style.
forEach Does Not Change the Array by Itself
Calling forEach does not automatically change the array.
const numbers = [1, 2, 3];
numbers.forEach((number) => {
number * 2;
});
console.log(numbers); // [1, 2, 3]The expression number * 2 creates a value, but nothing uses it.
If you mutate the array inside the callback, then the array can change:
const numbers = [1, 2, 3];
numbers.forEach((number, index, array) => {
array[index] = number * 2;
});
console.log(numbers); // [2, 4, 6]This is possible, but it is not always the clearest choice.
If you want a transformed array, prefer map.
forEach and Async Code
Be careful with async code inside forEach.
This pattern often does not do what beginners expect:
const ids = [1, 2, 3];
ids.forEach(async (id) => {
await fetch(`/api/users/${id}`);
});
console.log("Done");The forEach method does not wait for async callbacks to finish.
"Done" may log before the requests complete.
You will learn async JavaScript later, but remember this rule:
forEach is not designed for awaiting async work.When you need to wait for async operations, other patterns are usually better.
Best Practices
Use forEach for side effects:
users.forEach((user) => {
console.log(user.name);
});Use arrow functions for short callbacks:
numbers.forEach((number) => console.log(number));Use a named callback if the logic is longer:
function logUser(user) {
console.log(`${user.name} (${user.role})`);
}
users.forEach(logUser);Use for...of if you need break or continue:
for (const user of users) {
if (user.isBlocked) {
break;
}
console.log(user.name);
}Use map when you need a new transformed array:
const doubled = numbers.map((number) => number * 2);Common Mistakes
Mistake 1: Expecting forEach to Return a New Array
const numbers = [1, 2, 3];
const doubled = numbers.forEach((number) => {
return number * 2;
});
console.log(doubled); // undefinedUse map instead:
const doubled = numbers.map((number) => {
return number * 2;
});
console.log(doubled); // [2, 4, 6]Mistake 2: Trying to Use break
numbers.forEach((number) => {
if (number === 3) {
break;
}
});This is invalid.
Use for...of when you need to stop early.
Mistake 3: Thinking return Stops the Whole forEach
const numbers = [1, 2, 3, 4];
numbers.forEach((number) => {
if (number === 3) {
return;
}
console.log(number);
});Output:
1
2
4The return skips only the callback for 3.
It does not stop the entire forEach.
Mistake 4: Forgetting the Index Is the Second Argument
const colors = ["Red", "Green", "Blue"];
colors.forEach((index, color) => {
console.log(index, color);
});This is backwards.
The first argument is the current value.
The second argument is the index.
Correct:
colors.forEach((color, index) => {
console.log(index, color);
});Quick Check
What does this log?
const fruits = ["Apple", "Banana"];
fruits.forEach((fruit) => {
console.log(fruit);
});It logs:
Apple
BananaWhat does this return?
const numbers = [1, 2, 3];
const result = numbers.forEach((number) => number * 2);It returns:
undefinedforEach always returns undefined.
What should you use if you want [2, 4, 6] from [1, 2, 3]?
Use map:
const doubled = numbers.map((number) => number * 2);Summary
forEach runs a callback once for each element in an array.
- It is a higher-order function.
- The callback receives
currentValue,index, and the original array. - It is best for side effects like logging or updating the page.
- It always returns
undefined. - You cannot use
breakorcontinueinsideforEach. returninside the callback only exits the current callback call.- Use
for...ofwhen you need loop control. - Use
mapwhen you need a new transformed array.