Course: JavaScript Intermediate
Lesson 5: Array Methods: forEach, map, filter, and find
Level
Intermediate
Estimated Reading Time
10–15 minutes
Goal
By the end of this lesson, the learner will be able to:
- Use
forEach,map,filter, andfindon arrays - Explain what each method returns and when to choose each one
- Chain array methods to transform data for display in the UI
Frontend Development Context
Frontend development constantly involves lists of data — products, users, posts, scores, notifications. Knowing how to transform and filter arrays without writing manual loops is one of the most practical JavaScript skills you can have. Methods like map and filter are the backbone of how React, Vue, and other frameworks render lists of components from data.
These four methods — forEach, map, filter, and find — cover the majority of list-processing tasks. Rather than writing for loops that modify external variables, these methods make your intent explicit: you are iterating, transforming, filtering, or searching. Code that uses them is shorter, more readable, and less likely to introduce off-by-one bugs.
Explanation
forEach iterates over each element in an array and runs a callback for each one. It does not return a new array — it returns undefined. Use forEach when you want side effects like updating the DOM or logging, not when you need a transformed result.
map also iterates over each element, but it returns a new array where each element is the result of the callback. The original array is not modified. Use map when you want to transform every item: converting raw data to display strings, extracting a single property, or formatting values.
filter returns a new array containing only the elements for which the callback returned true. Elements that fail the condition are excluded. Use filter when you want a subset of the original array based on some condition.
find returns the first element for which the callback returns true, or undefined if no element matches. It stops as soon as it finds a match, making it more efficient than filter when you only need one item.
These methods can be chained: filter the array to get a subset, then map it to transform the results. This is a powerful pattern for preparing data before rendering it to the page.
Code Example
This example uses all four methods on the same dataset of course lessons.
const lessons = [
{ id: 1, title: "Scope", level: "intermediate", completed: true },
{ id: 2, title: "Hoisting", level: "intermediate", completed: false },
{ id: 3, title: "Arrow Functions",level: "intermediate", completed: true },
{ id: 4, title: "Array Methods", level: "intermediate", completed: false },
{ id: 5, title: "Destructuring", level: "advanced", completed: false },
];
// forEach — side effect only, no return value
lessons.forEach(lesson => {
if (lesson.completed) console.log(`✅ ${lesson.title}`);
});
// map — transform each item into a display string
const titles = lessons.map(lesson => lesson.title);
console.log(titles);
// ["Scope", "Hoisting", "Arrow Functions", "Array Methods", "Destructuring"]
// filter — get only intermediate lessons not yet completed
const todo = lessons.filter(
lesson => lesson.level === "intermediate" && !lesson.completed
);
console.log(todo.map(l => l.title)); // ["Hoisting", "Array Methods"]
// find — get the first lesson with a specific id
const lesson4 = lessons.find(lesson => lesson.id === 4);
console.log(lesson4.title); // "Array Methods"
Code Explanation
forEach loops over all lessons and logs a checkmark for completed ones. Notice that forEach does not produce a usable return value — it is purely for side effects.
map extracts just the title from each lesson object, producing a new array of strings. The original lessons array is untouched. This is the standard way to prepare data for rendering — take raw objects and pull out exactly what you need to display.
filter combines two conditions with && to get only intermediate lessons that have not been completed yet. The result is a new array of matching lesson objects. Chaining .map(l => l.title) on that result extracts the titles for display.
find searches for the first lesson where id === 4. It returns the matching object directly (not wrapped in an array). If no lesson matched, it would return undefined, which is why real code often checks the result before using it.
Pattern Highlights
✅ Positive Pattern: Chain
filterandmaptogether — filter to get the right items, then map to get the right shape. This is one of the most common data-preparation patterns in frontend code.
⚠️ Neutral Note:
findreturns the first match and stops. If you need all matching items, usefilter. If you need to know whether any match exists, usesomeinstead.
❌ Negative Pattern: Do not use
forEachwhen you need a return value.forEachalways returnsundefined. If you need a transformed array, usemap; if you need a subset, usefilter.
Common Mistakes
Mistake 1: Trying to use the return value of forEach
Storing the result of forEach expecting a new array.
const result = [1, 2, 3].forEach(n => n * 2);
console.log(result); // undefined — forEach does not return an array
forEach is for side effects only. Use map to create a new transformed array.
Mistake 2: Mutating the original array inside map
Modifying items inside the map callback instead of returning new values.
const lessons = [{ title: "Scope", done: false }];
const updated = lessons.map(lesson => {
lesson.done = true; // mutates the original object
return lesson;
});
Both lessons and updated now point to the same objects. To avoid mutation, return a new object: return { ...lesson, done: true }.
Mistake 3: Expecting find to return an array
Treating the result of find as an array when it returns a single value or undefined.
const users = [{ id: 1, name: "Alice" }, { id: 2, name: "Bob" }];
const match = users.find(u => u.id === 2);
console.log(match.length); // TypeError: Cannot read properties of undefined (if not found)
find returns one item, not an array. Check that the result is not undefined before accessing properties on it.
Quick Recap
forEachiterates and runs a callback for side effects — it returnsundefinedmaptransforms every element and returns a new array of the same lengthfilterreturns a new array containing only elements where the callback returnedtruefindreturns the first matching element (orundefined) and stops searching immediately