Skip to content

forEach and map

The for loop is universal — it can do anything. That generality is also its weakness. When you read a for loop, you have to read the whole body to understand its purpose. forEach and map communicate intent before you even read the callback.

forEach calls a function once for every item in the array. It does not return anything — it is for side effects: logging, updating the DOM, calling another function with each item.

const expenses = [
{ id: 1, description: 'Coffee', amount: 4.50, category: 'Food' },
{ id: 2, description: 'Bus pass', amount: 30.00, category: 'Transport' },
{ id: 3, description: 'Lunch', amount: 12.75, category: 'Food' },
];
expenses.forEach(expense => {
console.log(`${expense.description}: $${expense.amount}`);
});
// Coffee: $4.50
// Bus pass: $30.00
// Lunch: $12.75

The callback receives three arguments: the current item, its index, and the array itself. You only need what you use:

expenses.forEach((expense, index) => {
console.log(`${index + 1}. ${expense.description}`);
});
// 1. Coffee
// 2. Bus pass
// 3. Lunch

Key rule: forEach always returns undefined. Never assign its result to a variable expecting a transformed array — use map for that.

map calls a function once for every item and returns a new array containing the return value of each call. The original array is unchanged. Use map when you want to transform an array into a new array of the same length.

const descriptions = expenses.map(expense => expense.description);
console.log(descriptions); // ['Coffee', 'Bus pass', 'Lunch']
const amounts = expenses.map(expense => expense.amount);
console.log(amounts); // [4.50, 30.00, 12.75]

The callback receives the same three arguments as forEach (item, index, array). You return the value you want in the new array.

map shines when you need to reshape objects — extract certain fields, add computed properties, or rename keys:

const summaries = expenses.map(expense => ({
label: expense.description,
cost: `$${expense.amount.toFixed(2)}`,
}));
console.log(summaries);
// [
// { label: 'Coffee', cost: '$4.50' },
// { label: 'Bus pass', cost: '$30.00' },
// { label: 'Lunch', cost: '$12.75' },
// ]

Note the parentheses around the object literal ({...}). Without them, JavaScript interprets { as the start of the function body rather than an object.

Use map when…Use forEach when…
You need a new transformed arrayYou need side effects only
The callback returns a valueThe callback doesn’t return anything useful
You chain further methods afterwardYou are done after iterating

Never use map just to iterate — if you discard the return value, use forEach. Never use forEach when you need the transformed array — use map.

In BudgetBuddy, the expense list in the DOM is built by mapping the expenses array to HTML strings, then joining them:

function renderExpenses(expenses) {
const rows = expenses.map(expense => `
<li class="expense-item">
<span class="expense-desc">${expense.description}</span>
<span class="expense-cat">${expense.category}</span>
<span class="expense-amount">$${expense.amount.toFixed(2)}</span>
</li>
`);
document.querySelector('#expense-list').innerHTML = rows.join('');
}

One map call, one join, one DOM write. No loop, no manual string building, no index tracking.

Using the full BudgetBuddy expenses array from the previous lesson:

const expenses = [
{ id: 1, description: 'Coffee', amount: 4.50, category: 'Food', date: '2024-01-15' },
{ id: 2, description: 'Bus pass', amount: 30.00, category: 'Transport', date: '2024-01-14' },
{ id: 3, description: 'Lunch', amount: 12.75, category: 'Food', date: '2024-01-15' },
{ id: 4, description: 'Gym membership', amount: 45.00, category: 'Health', date: '2024-01-10' },
{ id: 5, description: 'Dinner out', amount: 38.20, category: 'Food', date: '2024-01-16' },
];
  1. Use forEach to log each expense description to the console.
  2. Use map to create an array of all expense amounts.
  3. Use map to create an array of objects with just { description, amount } — drop all other fields.
  4. Use map to add a formattedAmount property to each expense (e.g., '$4.50') — keep all other fields.

Log each result to confirm it looks right.

  • forEach iterates for side effects — DOM updates, logging, calling functions. It returns undefined.
  • map transforms every item and returns a new array of the same length. The original is unchanged.
  • Use map when you need the result array. Use forEach when you do not.
  • map is the foundation of rendering lists in the DOM — map data to markup strings, join, and write once.