Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Implementing Custom Iteration with JavaScript Protocols

Tech May 13 1

Understanding Iteration Protocols

In JavaScript, the iteration protocol consists of two parts: the iterator protocol and the iterable protocol. An object conforms to the iterator protocol if it has a next() method that returns an object with value and done properties. To be iterable, an object must implement a method under the well-known symbol Symbol.iterator, which returns a valid iterator.

Manual Iterator Example

Consider a custom range iterator:

const range = {
  start: 1,
  end: 5,
  next() {
    if (this.start < this.end) {
      return { value: this.start++, done: false };
    }
    return { done: true };
  }
};

This iterator works when manually calling next(), but cannot be used in for...of loops because it lacks the Symbol.iterator method.

Making Objects Iterable

To enable for...of usage, atttach a Symbol.iterator method that returns the iterator itself:

range[Symbol.iterator] = function () {
  return this;
};

Now for (const val of range) { ... } works as expected.

Iterating Plain Objects

Plain objects aren't iterable by default. We can make them iterable by defining Symbol.iterator:

const data = { x: 10, y: 20, z: 30 };
data[Symbol.iterator] = function* () {
  for (const key of Object.keys(this)) {
    yield [key, this[key]];
  }
};

This allows destructuring key-value pairs directly in loops:

for (const [k, v] of data) {
  console.log(k, v);
}

Using Generators for Simplicity

Generator functions automatically satisfy both protocols. The following generator yields indexed array elements without mutating the original array:

function* enumerate(arr) {
  for (let i = 0; i < arr.length; i++) {
    yield [arr[i], i];
  }
}

const letters = ['a', 'b', 'c'];
for (const [value, index] of enumerate(letters)) {
  console.log(value, index);
}

This approach avoids side effects like modifying built-in prototypes, which could break other code relying on standard iteration behavior (e.g., array destructuring).

Built-in Iterable Types

Native types like Array, String, Map, and Set are iterable because their prototypes include a Symbol.iterator method. This enables seamless use with for...of, spread syntax (...), and destructuring.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.