map, filter, and reduceJavaScript array iteration methods loop over elements cleanly without manual index counters. Functional methods like map(), filter(), and reduce() produce new values instead of mutating data in place, which makes state bugs far less likely.
Each array iteration method accepts a callback function that receives (element, index, array) on every pass. Pick the method that matches your exact output shape:
| Method | Return Value | Common Use Case |
|---|---|---|
map(fn) |
New array of same length | Transform every item into a new shape |
filter(fn) |
New array (0 to N items) | Keep only items passing a condition |
reduce(fn, init) |
Single accumulated value | Sum totals, group counts, merge records |
forEach(fn) |
undefined |
Run side effects like logging |
flatMap(fn) |
Flattened new array | Map and flatten 1 level in one pass |
When chaining filter() followed by map(), keep callbacks pure and short. Avoid modifying external variables inside map() or filter() so your data pipeline stays easy to test.
Chaining filter(), map(), and reduce() turns raw cart items into an accurate checkout total in just a few lines.
const cart = [
{ name: "USB Cable", price: 12, qty: 2, inStock: true },
{ name: "Laptop Stand", price: 45, qty: 1, inStock: false },
{ name: "Webcam", price: 60, qty: 1, inStock: true },
];
const availableNames = cart
.filter((item) => item.inStock)
.map((item) => item.name);
const availableTotal = cart
.filter((item) => item.inStock)
.reduce((sum, item) => sum + item.price * item.qty, 0);
console.log("Available:", availableNames);
console.log("Subtotal: $", availableTotal);
map() instead of forEach() for side effects: map() allocates a brand-new array; if you ignore the returned array, use forEach() or for...of.return inside {} arrow callbacks: items.map(x => { x * 2 }) returns [undefined, ...]. Either omit braces x => x * 2 or write return x * 2;.reduce(): Calling [].reduce((a, b) => a + b) on an empty array throws a TypeError. Always pass an initial value like 0 or {}.forEach() early with break?No, break is invalid inside forEach(), and return only skips the current callback call. Use a for...of loop when you need early break control.
for...of over map() or reduce()?Use for...of when you run await sequentially inside a loop or need to break out early on a condition.
map() skip empty slots in sparse arrays?Yes, map(), filter(), and forEach() skip uninitialized holes in sparse arrays, though normal dense arrays never have holes.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With
Experiment with the code from this lesson in our interactive playground.