Array Iteration
Iterating over an array is one of the most common things a JavaScript program does. Beyond the plain for loop you have a family of iteration methods — forEach, find, some, every, indexOf, includes — each tuned for a specific question. Picking the right one makes code shorter, faster and self-documenting.
forEach — run a side effect per element
forEach calls a function once for each element. It returns undefined — its whole point is the side effect. It is not what you want if you intend to build a new array (that is map) or to bail out early (you cannot break out of forEach).
const users = [
{ id: 1, name: "Ada" },
{ id: 2, name: "Lin" },
{ id: 3, name: "Pedro" },
];
users.forEach((user, index, arr) => {
console.log(`#${index + 1} ${user.name} of ${arr.length}`);
});#1 Ada of 3 #2 Lin of 3 #3 Pedro of 3
find, findIndex, findLast, findLastIndex
Use these when you want the first match (or last, with the *Last variants). The callback returns a boolean; the method returns the matching element (or its index), or undefined / -1 if nothing matches.
const products = [
{ sku: "A1", price: 10 },
{ sku: "A2", price: 25 },
{ sku: "A3", price: 25 },
{ sku: "A4", price: 60 },
];
products.find(p => p.price > 20); // { sku: "A2", price: 25 }
products.findIndex(p => p.price > 20); // 1
products.findLast(p => p.price === 25); // { sku: "A3", price: 25 }
products.findLastIndex(p => p.price > 100); // -1some and every — boolean questions
some answers "is there at least one element that matches?" every answers "do all elements match?" Both short-circuit: some stops at the first match, every at the first failure.
const ages = [21, 33, 19, 45]; ages.some(a => a < 18); // false — anyone under 18? ages.every(a => a >= 18); // true — everyone an adult? // Edge cases worth knowing [].every(x => false); // true — vacuously true [].some(x => true); // false — vacuously false
The empty-array cases come from formal logic: a universal statement over no elements is true, an existential statement over no elements is false. They occasionally bite you in real code, so worth remembering.
indexOf and lastIndexOf
These look for a strict equality match (===) and return the position, or -1 if not found. They are perfect for primitives but useless for searching by object content.
const words = ["red", "green", "blue", "green"];
words.indexOf("green"); // 1
words.indexOf("green", 2); // 3 — start searching from index 2
words.lastIndexOf("green"); // 3
words.indexOf("purple"); // -1
// Watch out — reference equality
const items = [{ id: 1 }, { id: 2 }];
items.indexOf({ id: 1 }); // -1 — different object
items.findIndex(x => x.id === 1); // 0includes — readable membership test
includes(value) is the modern, readable way to ask "is this value in the array?" It uses the same equality rules as indexOf with one improvement: it can find NaN.
const colors = ["red", "green", "blue"];
colors.includes("red"); // true
colors.includes("purple"); // false
colors.includes("red", 1); // false — start from index 1
// NaN quirk
const nums = [1, NaN, 3];
nums.indexOf(NaN); // -1 !
nums.includes(NaN); // trueChoosing the right method
Looking for one thing?
find(element) orfindIndex(position).Counting matches or building a subset? Switch to
filterorreduce— see the next page.Boolean question?
somefor "any",everyfor "all".Membership of a primitive?
includes.indexOfonly if you also need the position.Running a side effect on each item?
forEach— but a plainfor...ofis often clearer and supportsbreak.Need to bail out early? Use
for,for...of, orsome(returntruewhen done).
A composed example
Real-world combination
const orders = [
{ id: 1, total: 49, status: "paid" },
{ id: 2, total: 0, status: "pending" },
{ id: 3, total: 120, status: "paid" },
{ id: 4, total: 12, status: "refunded" },
];
// Quick checks
const anyRefunded = orders.some(o => o.status === "refunded"); // true
const allHaveTotal = orders.every(o => typeof o.total === "number"); // true
// Pull the first big-spender
const big = orders.find(o => o.status === "paid" && o.total > 100);
// → { id: 3, total: 120, status: "paid" }
// Or just the membership test
const hasOrder1 = orders.map(o => o.id).includes(1); // trueIteration methods chain well — and that is the doorway to the next page, on map, filter and reduce, where the same callback style is used to transform rather than just inspect an array.