Tutorials Logic, IN info@tutorialslogic.com

JavaScript Loops for, while, forEach, map, filter

Looping Statements

Looping statement enable our JavaScript program to continuously execute a piece of code as long as a specified condition is true. Looping statement makes the JavaScript code compact. There are besically five types of looping statements-

  • The for loop.
  • The while loop.
  • The do-while loop.
  • The for-in loop.
  • The for-of loop.

The for Loop

A for loop repeats a piece of code until a specified condition is true. The for Loop has three important parts i.e. Initialization, Condition, and Increment/Decrement.

Javascript Looping Statements Syntax

Javascript Looping Statements Syntax
for (Initialization; Condition; Increment/Decrement) {
	...........
}

Javascript Looping Statements Worked Example

Javascript Looping Statements Worked Example
for (i = 0; i <=5; i++) {
	console.log(i);
}

The while Loop

The while loop is a more simple version of the for, which repeats a piece of code until a specified condition is true.

Javascript Looping Statements Worked Example 2

Javascript Looping Statements Worked Example 2
let i = 10;
while (i > 0) {
	console.log(i);
	i--;
}

The do-while Loop

The do-while loop is very similar to the while loop, but it executed at least once whether the condition is true or false, because condition check happens at the end of the loop.

Javascript Looping Statements Worked Example 3

Javascript Looping Statements Worked Example 3
let i = 0;
do {
	i++;
	console.log(i);
} while (i <= 5);

The for-in Loop

The for-in loop is a special kind of a loop in JavaScript which iterates over the properties name of an object, or the elements of an array.

Javascript Looping Statements Worked Example 4

Javascript Looping Statements Worked Example 4
let datas = [3, 5, 7, 9, 11];
for (var data in datas) {
	console.log(data); // 0, 1, 2, 3, 4
}

The for-of Loop

A `for...of` loop iterates values from an iterable such as an array, string, map, set, or generator. Use `for...in` for enumerable property keys, not array values.

Javascript Looping Statements Worked Example 5

Javascript Looping Statements Worked Example 5
let datas = [3, 5, 7, 9, 11];
for (var data of datas) {
	console.log(data); // 3, 5, 7, 9, 11
}

break and continue

The break statement exits a loop immediately. The continue statement skips the current iteration and moves to the next one.

break and continue - JavaScript Example

break and continue - JavaScript Example
// break - exit loop when 5 is found
for (let i = 0; i < 10; i++) {
  if (i === 5) break;
  console.log(i); // 0, 1, 2, 3, 4
}

// continue - skip even numbers
for (let i = 0; i <= 10; i++) {
  if (i % 2 === 0) continue;
  console.log(i); // 1, 3, 5, 7, 9
}

// Nested loop with labeled break
outer: for (let i = 0; i < 3; i++) {
  for (let j = 0; j < 3; j++) {
    if (j === 1) break outer; // breaks both loops
    console.log(`i=${i}, j=${j}`);
  }
}
// Output: i=0, j=0

Array Iteration Methods (Modern Loops)

ES5+ provides functional iteration methods that are often cleaner than traditional loops for working with arrays.

Array Iteration

Array Iteration
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// forEach - iterate without return value
numbers.forEach((n, index) => console.log(`[${index}] = ${n}`));

// map - transform each element
const doubled = numbers.map(n => n * 2);
console.log(doubled); // [2,4,6,8,10,12,14,16,18,20]

// filter - keep elements matching condition
const evens = numbers.filter(n => n % 2 === 0);
console.log(evens); // [2,4,6,8,10]

// reduce - accumulate to single value
const sum = numbers.reduce((acc, n) => acc + n, 0);
console.log(sum); // 55

// find - first match
const firstOver5 = numbers.find(n => n > 5);
console.log(firstOver5); // 6

// some / every
console.log(numbers.some(n => n > 9));   // true
console.log(numbers.every(n => n > 0));  // true

Which Loop Should You Use?

Different loops are better for different situations. Choosing the right one makes your code easier to read and helps avoid common mistakes.

Loop Type Best Use Case Notes
for When you know the start, stop, and step. Best for indexed iteration and counting.
while When repetition depends on a condition. Useful when the number of iterations is unknown beforehand.
do...while When the body must run at least once. Good for menu loops and retry prompts.
for...in Iterating over object keys. Avoid using it for normal array value iteration.
for...of Iterating over iterable values. Ideal for arrays, strings, Maps, and Sets.
Array methods Transforming or filtering arrays. Use map(), filter(), reduce(), etc. for readable functional code.

Loop Selection and Invariants

Use a `for` loop when initialization, continuation condition, and update belong together. Use `while` when continuation depends on state changed by several operations, and `do...while` only when the body must run before the first test. Write the condition from the invariant and termination rule rather than copying an index template.

Before coding, state what has been processed, what remains, and why each iteration moves toward termination. An off-by-one bug usually comes from an unclear boundary: whether the end is inclusive, whether length is a count or last index, or whether the update occurs before or after access.

`break` exits the nearest loop or labeled statement; `continue` skips to the next iteration according to the loop form; `return` exits the entire function; `throw` transfers to an error boundary. Prefer a guard and continue for one exceptional item, but avoid many exits that make cleanup and invariants hard to follow.

A labeled break can leave nested loops without a separate flag, but a named helper that returns a result is often clearer. Choose the control structure that communicates the search, transformation, retry, traversal, or state-machine intent rather than minimizing lines.

  • State the boundary and termination argument before implementation.
  • Distinguish count, final index, and exclusive end.
  • Choose break, continue, return, or throw from ownership.
  • Extract nested searches when labels obscure the result.

Collections and Iteration Protocols

`for...of` consumes an iterable and yields its values. Arrays, strings, maps, sets, typed arrays, and many DOM collections are iterable. A string iteration yields Unicode code points rather than UTF-16 code units, which is often safer for visible characters but still does not equal user-perceived grapheme clusters.

`for...in` enumerates enumerable string property keys, including inherited keys unless filtered. It is intended for object properties, not array values; array keys are strings and extra enumerable properties can appear. For ordinary own object entries, use `Object.keys`, `Object.values`, or `Object.entries` with a deliberate ordering expectation.

Array methods express common intents: `map` transforms each element, `filter` selects, `find` stops at one match, `some` and `every` short-circuit predicates, `reduce` accumulates, and `forEach` performs iteration without producing a result. Do not force a complex stateful algorithm into reduce when a named loop is clearer.

Custom iterables implement `Symbol.iterator` and return an iterator whose `next` produces `{ value, done }`. Generators simplify that protocol and can clean up through `return` behavior when iteration ends early. Document whether iteration is repeatable, consumes a resource, or reflects mutations made during traversal.

  • Use for-of for iterable values and for-in for property keys.
  • Select an array method that names the intended result.
  • Avoid clever reduce chains that hide state transitions.
  • Define cleanup and repeatability for custom iterables.

Mutation and Traversal Safety

Changing a collection while traversing it can skip, repeat, or newly include items according to the collection and algorithm. Removing an array element shifts later indexes; appending can extend an index-based loop; Map and Set iteration have their own mutation semantics. Prefer building a new result or iterating a stable snapshot when correctness matters.

When in-place removal is required, iterate an array backward or maintain an index that advances only when no removal occurs. Explain the invariant and test consecutive matches. Avoid `delete` on array elements when a dense sequence is expected because it leaves an empty slot rather than shifting values.

Live DOM collections can change as matching nodes are inserted or removed, while static query results do not. Convert to an array or otherwise snapshot when the loop mutates the DOM. Batch DOM reads and writes to reduce forced layout, and use event delegation or observers instead of repeatedly scanning the entire document.

Shared mutable state can change between asynchronous iterations even though each synchronous job runs to completion. Capture the item identifier and revalidate current state before committing delayed work. Do not assume the collection still represents the same authorization, selection, or ordering after an await.

  • Prefer stable snapshots for mutation-heavy traversal.
  • Test consecutive removals and newly appended items.
  • Know whether a DOM collection is live or static.
  • Revalidate mutable state after asynchronous suspension.

Async Iteration and Performance

A `for...of` loop can await each item sequentially when order or capacity requires it. `for await...of` consumes async iterables and can also consume sync iterables through adaptation. Use it for streams or paginated producers that yield over time, and ensure early exit closes the iterator and underlying resource.

`forEach` does not await an async callback or collect its returned Promises. Use a sequential loop, `Promise.all` for a bounded independent set, or a concurrency-limited pool. Starting every operation with `map` before applying a limit is already unbounded; the limiter must control when each operation is created.

Optimize only after measuring. An algorithmic change from repeated linear lookup to a Set or Map matters more than replacing one loop syntax with another. Measure realistic collection size, key distribution, allocation, parsing, DOM work, and downstream calls. Keep correctness tests around any low-level optimization.

Long synchronous loops block input and rendering. Chunk non-urgent work with an appropriate scheduler, move suitable CPU work to a worker, or process a stream incrementally. Preserve cancellation, progress, and partial-result ownership. Yielding too frequently also adds overhead, so tune from responsiveness evidence.

  • Use sequential await only when the workflow requires it.
  • Limit operation creation, not only Promise collection.
  • Improve algorithmic complexity before micro-optimizing syntax.
  • Move or chunk long CPU loops to protect responsiveness.

Loop Tests and Diagnostics

Test an empty collection, one item, two items, the first and last match, no match, every item matching, consecutive removals, duplicate values, sparse arrays where supported, and the largest realistic input. For index ranges, test immediately below, at, and above each boundary. Verify the result and that input mutation matches the contract.

Property-based tests can assert invariants such as output length, preserved ordering, membership, sum, or round-trip behavior across many generated inputs. Include a maximum-iteration guard in tests for complex retry or state-machine loops so a termination defect fails quickly with diagnostic state rather than hanging the suite.

When a loop is slow, sample where time is spent instead of printing every iteration. Count iterations, allocations, lookups, awaits, DOM reads, and downstream calls. For async pools, test maximum observed concurrency, cancellation, partial failure, and resource cleanup. A correct final array does not prove capacity limits were respected while it was built.

  • Cover empty, boundary, duplicate, and maximum-size inputs.
  • Assert invariants in addition to exact examples.
  • Guard complex loops against non-termination in tests.
  • Measure peak concurrency and cleanup for async traversal.
Before you move on

JavaScript Loops for, while, forEach, map, filter Mastery Check

5 checks
  • Looping statement enable our JavaScript program to continuously execute a piece of code as long as a specified condition is true.
  • Looping statement makes the JavaScript code compact.
  • There are besically five types of looping statements-.
  • A for loop repeats a piece of code until a specified condition is true.
  • The for Loop has three important parts i.e.
Browse Free Tutorials

Explore 500+ free tutorials across 20+ languages and frameworks.