Module 31 // Core JavaScript

Iteration Protocols

Module Objective

Iterable vs iterator, Symbol.iterator, how for...of and spread work internally

Mental Model Realtime Simulation

INTERACTIVE_CANVAS
Editor_Pane
Loading...
Console_Output
Waiting for output...

Practical Code Examples

// Example 1
// 1. Custom Range Iterator
const range = {
  from: 1,
  to: 3,
  [Symbol.iterator]() {
    this.current = this.from;
    return this;
  },
  next() {
    if (this.current <= this.to) {
      return { done: false, value: this.current++ };
    } else {
      return { done: true };
    }
  }
};

for (let num of range) {
  console.log(num); // 1, 2, 3
}
💡 By implementing `[Symbol.iterator]`, we make the `range` object compatible with `for...of`, even though it's not an Array.
// Example 2
// 2. String Iteration
const str = "Hi";
const iter = str[Symbol.iterator]();

console.log(iter.next()); // { value: 'H', done: false }
console.log(iter.next()); // { value: 'i', done: false }
console.log(iter.next()); // { value: undefined, done: true }
💡 Strings are built-in iterables. You can manually request their iterator and 'walk' through the characters one by one.
// Example 3
// 3. Spread & Iteration
const nums = [1, 2];
const doubled = [...nums, 3]; // Uses iteration protocol

// The spread operator (...) works on ANY iterable, 
// not just arrays!
💡 Many modern JS features like spread and destructuring rely internally on these protocols to fetch data from objects.

Engine & Memory Architecture

Memory & State

1. Iterator State:

  • The Iterator maintains its Internal State (like this.current) in the Heap.
  • Unlike an Array, it doesn't need to store all items at once. It only stores the Current Index.

2. Symbolic Lookup:

  • Symbol.iterator is a unique key in the RAM.
  • Using a Symbol prevents collisions with other property names on your object.

3. CPU Overhead:

  • Each step of a for...of loop involves a function call to next().
  • Performance: For high-frequency loops, standard for loops with indices are faster because they avoid the overhead of the Iterator object and function calls.