Suggest an editImprove this articleRefine the answer for “How to iterate over an array with a loop?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)- Need an index, step control, break/continue: the classic for. - Only need the values, readability, and the ability to break: for...of. - Just run an action for every element with no need to break: forEach. - Need a new array/value: map, filter, reduce, some/every, find. - Sequential async traversal: for...of + await. Parallel: Promise.all with map. - Do not use for...in on arrays (it is for objects and can walk extra properties).Shown above the full answer for quick recall.Answer (EN)Image## Short answer - Need an index, step control, break/continue: the classic for. - Only need the values, readability, and the ability to break: for...of. - Just run an action for every element with no need to break: forEach. - Need a new array/value: map, filter, reduce, some/every, find. - Sequential async traversal: for...of + await. Parallel: Promise.all with map. - Do not use for...in on arrays (it is for objects and can walk extra properties). ## Detailed breakdown ### 1) The indexed for, maximum control Fits when you need an index, a step, an early exit, skipped iterations, and maximum performance on hot paths. ```javascript const arr = [10, 20, 30, 40]; for (let i = 0; i < arr.length; i++) { if (arr[i] === 30) continue; // skip 30 if (arr[i] > 35) break; // stop the loop console.log(i, arr[i]); // index and value } ``` ### 2) for...of, a convenient walk over values Simple syntax for values, supports break/continue/return from the enclosing function. For indices, use arr.entries(). ```javascript const arr = ['a', 'b', 'c']; for (const v of arr) { if (v === 'b') continue; // skip console.log(v); } // Index + value via entries() for (const [i, v] of arr.entries()) { console.log(i, v); } ``` ### 3) Array.prototype.forEach, no breaking out Runs a function for every element, but there is no break/continue; return only ends the callback. For an early exit, use for/for...of. ```javascript const arr = [1, 2, 3]; arr.forEach((value, index) => { // there is NO way to stop the whole forEach early console.log(index, value); }); ``` ### 4) while / do...while, when the condition comes first Used when the iterations are controlled by a condition rather than the array's length (for example, reading from a queue). ```javascript const queue = [1, 2, 3]; while (queue.length) { const item = queue.shift(); console.log(item); } do { // runs at least once } while (false); ``` ### 5) for...in, not for arrays Iterates over an object's enumerable keys, including inherited and string keys. For arrays it can give an unexpected order and "extra" properties. ```javascript const arr = [10, 20]; arr.extra = 42; // added a property for (const k in arr) { console.log(k); // '0', '1', 'extra', not what you expected } // Use for, for...of, or array methods instead. ``` ### Functional methods: map / filter / reduce / some / every / find Ideal when you need a new array/value built from the old one. They do not modify the source array (except for rare cases with mutations inside the callback). ```javascript const users = [ { id: 1, name: 'Ann', active: true }, { id: 2, name: 'Bob', active: false }, { id: 3, name: 'Cat', active: true }, ]; const activeNames = users .filter(u => u.active) // keep the active ones .map(u => u.name); // take the names const hasInactive = users.some(u => !u.active); // true/false const allActive = users.every(u => u.active); // true/false const byId = users.reduce((acc, u) => { acc[u.id] = u; // accumulate into an object return acc; }, {}); const firstInactive = users.find(u => !u.active); // the first match ``` ### Index + value If you need both the index and the value, use arr.entries() with for...of, or the second callback argument in forEach/map/filter. ```javascript const arr = ['x', 'y', 'z']; for (const [i, v] of arr.entries()) { console.log(i, v); } arr.forEach((v, i) => console.log(i, v)); ``` ### Breaking out and skipping iterations break/continue work with for/for...of/while. They are not available in forEach and the array methods (use conditional branches or other constructs instead). ```javascript const arr = [1, 2, 3, 4, 5]; for (const n of arr) { if (n % 2 === 0) continue; // skip even numbers if (n > 4) break; // stop at 5 console.log(n); } ``` ### Async traversals For sequential async operations, use for...of + await. For parallel execution, use map -> Promise.all. Do not use await inside forEach; it does not wait. ```javascript // Sequential async function processSequential(urls) { for (const url of urls) { const res = await fetch(url); console.log(url, res.status); } } // Parallel async function processParallel(urls) { const responses = await Promise.all(urls.map(url => fetch(url))); responses.forEach((res, i) => console.log(urls[i], res.status)); } // Anti-pattern: await inside forEach async function bad(urls) { urls.forEach(async (url) => { const res = await fetch(url); // does not wait for all of them console.log(res.status); }); // The function returns before all the fetches finish } ``` ### Performance and readability: key points - On hot paths the classic for is usually a bit faster, but the difference is rarely critical. - Pick the most readable option that fits the task (map/filter for transformations, for...of for a simple walk). - Avoid mutating the array while iterating over it (push/shift on the source array) unless that is required. ### Selection cheat sheet - Need a new array from an old one: map/filter/flatMap. - Need to accumulate a single value (sum, object, map): reduce. - Find/check: find/some/every. - A simple walk over values with the ability to break: for...of. - Index, step, complex conditions, performance: the classic for. - Sequential async: for...of + await. - Parallel async: Promise.all + map.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.