Blog / Javascript

What are JavaScript Generators and Iterators

What are JavaScript Generators and Iterators

In this post find out about what are JavaScript Generators and Iterators

Will MaygerWill Mayger
June 11, 2023
Article

JavaScript generators and iterators are powerful features introduced in ECMAScript 2015 (ES6) that provide a way to define custom iterable objects and control the flow of iteration. Generators allow you to create functions that can be paused and resumed, while iterators enable you to iterate over collections or custom data structures. In this article, we will explore the concepts of JavaScript generators and iterators, their syntax, and how they can be used to enhance your code.

Table of Contents

  • Introduction to Generators and Iterators
  • Generators in JavaScript
    • Generator Function Syntax
    • Yielding Values
    • Iteration Control
    • Generator Return Value
  • Iterators in JavaScript
    • Iterable and Iterator Protocols
    • Creating Custom Iterators
    • Using the for...of Loop
  • Generator-Iterator Combination
  • Use Cases and Benefits
  • Conclusion

Introduction to Generators and Iterators

Generators and iterators are closely related concepts in JavaScript. While generators define the behavior of functions that can be paused and resumed, iterators provide a way to traverse through a collection or custom data structure.

Generators are special functions that can be exited and later re-entered, allowing the function execution to be paused and resumed at any point. This makes generators different from regular functions, as they don’t run to completion on a single call.

On the other hand, iterators are objects that define a sequence and enable iteration over that sequence. They provide a consistent way to traverse through elements of a collection or data structure, regardless of its internal implementation.

Together, generators and iterators allow you to build custom iterable objects and control the flow of iteration.

Generators in JavaScript

Generators are defined using generator functions, which are a special type of function denoted by an asterisk (*) after the function keyword. Generator functions can be paused and resumed using the yield keyword.

Generator Function Syntax

Here’s an example of a basic generator function:

function* myGenerator() {
  // Generator function body
}

The function* syntax indicates that myGenerator is a generator function. Inside the function body, we can use the yield keyword to pause the generator and return a value.

Yielding Values

The yield keyword is used within generator functions to produce a value that can be consumed by the iterator. When the generator encounters a yield statement, it pauses its execution and returns the yielded value.

function* myGenerator() {
  yield 'Hello';
  yield 'World';
}

In this example, the generator function myGenerator yields the strings 'Hello' and 'World' successively. Each time the generator is iterated, it produces the next value in the sequence.

Iteration Control

Generators provide fine-grained control over the iteration process. By using yield statements, you can control when and how the generator produces values.

function* counter() {
  let count = 0;
  while (true) {
    yield count++;
  }
}

In this example, the counter generator produces an infinite sequence of increasing numbers. Each time the generator is iterated, it yields the next incremented value.

Generator Return Value

Generators can have an optional return value that is specified using the return statement.

function* myGenerator() {
  yield 'Hello';
  yield 'World';
  return 'Finished';
}

When a generator is done iterating, either by reaching the end or encountering a return statement, its next() method returns an object with the value property set to the returned value and the done property set to true.

Iterators in JavaScript

Iterators provide a standard way to traverse through elements of a collection or custom data structure. They implement the iterable and iterator protocols, enabling iteration using the for...of loop or by manually calling the next() method.

Iterable and Iterator Protocols

In JavaScript, an iterable is an object that defines its iteration behavior by implementing the @@iterator method. The @@iterator method returns an iterator object.

An iterator is an object that implements the next() method, which returns an object with two properties: value (the current yielded value) and done (a boolean indicating whether iteration has finished).

Creating Custom Iterators

You can create custom iterators by defining the @@iterator method on your objects. The @@iterator method should return an iterator object.

Here’s an example of a custom iterable object:

const myIterable = {
  data: ['apple', 'banana', 'cherry'],
  [Symbol.iterator]() {
    let index = 0;
    return {
      next: () => {
        if (index < this.data.length) {
          return { value: this.data[index++], done: false };
        } else {
          return { done: true };
        }
      }
    };
  }
};

In this example, myIterable is an object that defines an iterator by implementing the @@iterator method. The iterator’s next() method is defined to return the next value in the data array until the end is reached.

Using the for...of Loop

The for...of loop can be used to iterate over any iterable object, including arrays, strings, maps, sets, and custom iterables.

for (const item of myIterable) {
  console.log(item);
}

In this example, the for...of loop iterates over the myIterable object, printing each value ('apple', 'banana', 'cherry') to the console.

Generator-Iterator Combination

Generators and iterators can be combined to create powerful and flexible iteration patterns. By using generators to define the iteration logic and iterators to consume the generated values, we can create custom iterable objects with fine-grained control.

const myIterable = {
  *[Symbol.iterator]() {
    let count = 0;
    while (count < 5) {
      yield count++;
    }
  }
};

for (const item of myIterable) {
  console.log(item);
}

In this example, the myIterable object uses a generator function defined with function* to define its iteration logic. The generator yields values from 0 to 4, creating a custom iterable that can be iterated using the for...of loop.

Use Cases and Benefits

JavaScript generators and iterators provide several benefits and use cases in real-world applications:

  • Asynchronous Programming: Generators can be used to simplify asynchronous code by pausing and resuming execution using yield statements. This is especially useful when dealing with long-running or non-blocking operations.

  • Lazy Evaluation: Generators enable lazy evaluation, allowing you to generate values on demand instead of precomputing them. This can improve performance and memory usage when working with large data sets.

  • Custom Iterables: By combining generators and iterators, you can create custom iterable objects that provide tailored iteration behavior for specific use cases. This allows for more expressive and efficient iteration patterns.

  • Data Processing: Generators can be used to process large data sets or streams by generating values one at a time. This is particularly useful when dealing with data that doesn’t fit entirely into memory.

  • Infinite Sequences: Generators allow the creation of infinite sequences of values, enabling powerful algorithms and calculations that rely on continuous data generation.

Conclusion

In this article, we explored the concepts of JavaScript generators and iterators. We learned how generators allow the creation of functions that can be paused and resumed, and how iterators provide a way to traverse through collections or custom data structures. By understanding and using generators and iterators, you can enhance your code with fine-grained control over iteration and create custom iterable objects tailored to your specific needs.

Generators and iterators offer numerous benefits, including simplified asynchronous programming, lazy evaluation, custom iterables, efficient data processing, and support for infinite sequences. They provide powerful tools to enhance the functionality and flexibility of your JavaScript applications.

There we have what are JavaScript Generators and Iterators, if you want more like this be sure to check out some of my other posts!

Foxi - Budget Planner & Tracker

Foxi

Budget Planner & Tracker

More money in your pocket by the end of the month.

Free to use and no account needed.

Get started now.

Get the app

Some graphics used on this post were made using icons from flaticon.

Latest Posts

Learn React, JavaScript and TypeScript

Learn React, JavaScript and TypeScript

Join the platform that top tier companies are using.
Master the skills you need to succeed as a software engineer and take your career to the next level with Pluralsight.

Start here

Become an expert in ReactJS, TypeScript, and JavaScript.

Here you will find my personal recomendations to you, for full disclosure I earn a small commission from some of these links, but I only recommend what I trust and personally use.

Good things are coming, don't miss out!

Good things are coming, don't miss out!

Follow me on Twitter to stay up to date and learn frontend, React, JavaScript, and TypeScript tips and tricks!

Are you a novice, intermediate or expert react engineer?

Find out here by taking my fun, interactive, quick quiz which takes approximately 1 - 3 minutes. How well will you will do?

Foxi - Budget Planner & Tracker

Foxi

Budget Planner & Tracker

More money in your pocket by the end of the month.

Free to use and no account needed.

Get started now.

Get the app