Frontend Labs
⋯

8. Arrays and iteration: methods, iterators, generators

Arrays are objects with numeric keys and a length that auto-updates. The functional methods (map/filter/reduce) don't mutate; a handful of older methods (push, splice, sort, reverse) do — know which is which, since mutating a shared array is a classic bug source in UI state.

const nums = [1, 2, 3, 4, 5];
nums.map(n => n * 2);              // [2,4,6,8,10] — new array
nums.filter(n => n % 2 === 0);     // [2,4]        — new array
nums.reduce((sum, n) => sum + n, 0); // 15          — folds to one value
nums.sort((a, b) => b - a);        // MUTATES nums in place, now [5,4,3,2,1]

The iterator protocol is what makes for...of, spread (...), and destructuring work on arrays, Map, Set, strings, and any custom object that implements Symbol.iterator:

class Range {
  constructor(start, end) { this.start = start; this.end = end; }
  [Symbol.iterator]() {
    let current = this.start, end = this.end;
    return {
      next() {
        return current <= end
          ? { value: current++, done: false }
          : { value: undefined, done: true };
      },
    };
  }
}
[...new Range(1, 5)];        // [1,2,3,4,5] — works because Range implements the protocol
for (const n of new Range(1, 3)) console.log(n); // 1, 2, 3

Generators (function*) are a shortcut for writing iterators without hand-rolling next():

function* range(start, end) {
  for (let i = start; i <= end; i++) yield i;
}
[...range(1, 5)];   // [1,2,3,4,5]

Generators also underpin how async iteration and (historically) some coroutine-style async patterns work — yield pauses execution and hands a value out, exactly like await pauses on a promise (§14).

Generated from real-life-JS-guide.md · 8 Oct 2026 16:36