Blogs
Apr 14 • Amit Barletz

Iterators and Generators in JavaScr

Mastering JavaScript Generators: Deep Dive and Advanced Use Cases

For a long time, I've been intrigued by iterators and generators in JavaScript. These powerful features have the potential to significantly improve the way we write code, making it more efficient (spoiler alert: disclaimer in the Performance Considerations section), readable, and elegant.

However, every time I tried to learn about them, I found myself struggling to wrap my head around the concepts and eventually gave up. But I was determined not to let the challenges deter me. I decided to embark on a personal journey to learn and master iterators and generators, despite the obstacles I had faced before.

In this article, we will dive deeper into generators, explore their advanced use cases, and learn how to harness their full potential. You can find all the code examples (and even more) in this repository on GitHub.

Overview

Iterators and generators provide a mechanism for customizing the behavior of for-of loops and other constructs that iterate over data.

Iterators are objects that provide a standard interface for iterating over a collection of values. They implement the iterable protocol by having a next() method that returns an object with a value property that represind the next value in the iteration sequence, and a done property that indicates whether the iterator is finished (boolean).

{
  value: any, // any data type
  done: boolean
}

An iterator object, once created, can be explicitly iterated by calling next() repeatedly. The process of iterating over an iterator is known as consuming the iterator since it is typically performed only once. After yielding a terminating value, any subsequent calls to next() should continue to return

{
    value: undefined,
    done: true
}

The following createRangeIterator function that takes start, end, and a step parameters and returns an object with a next() method, which updates the current value and increments the iterationCount. When the current value reaches or exceeds the end, the iterator returns the iterationCount and sets done to true.

function createRangeIterator(start, end, step = 1) {
  let current = start
  let iterationCount = 0

  return {
    next: function () {
      if (current < end) {
        const value = current
        current += step
        iterationCount++
        return { value, done: false }
      }

      return { value: iterationCount, done: true }
    },
  }
}

const iterator = createRangeIterator(0, 10, 2)

let result = iterator.next()

do {
  result = iterator.next()
  console.log(result.value)
} while (!result.done)

// Output:
// 0
// 2
// 4
// 6
// 8
// Final return value (iterationCount): 5

  • Share to Facebook
  • Youtube link
Related PostsSee all