Quick comparison between Iterators & Generators

Merna Zakaria
5 min readOct 25, 2020

1. Iterators

1.1 Definition

Iterators are a new way to loop over any collection in JavaScript, they were introduced in ES6 .

In JavaScript, we can loop over an Array using for-of loop

for (let item in iterable) { // use `item` }

This loop extracts each item in the array. This process of extracting one item and doing something with it is called iteration.

The objects that support iteration is called an iterable. In JavaScript built-in data types like String and Array are iterables , but Object to become iterable, it must have an iterator object.

This iterator object must follow iterator protocol, which tells to have the next method on the iterator object because this method will be called multiple times when iteration is performed.

1.2 Why do we need iterators?

We need iterators to implement iterables which enable us to loop over data structure that not iterable like object but with extra boilerplate code.

1.3 Example

1.4 How to create Iterators?

For creating an iterator function, we use Symbol.iterator.

Symbol.iterator will return an object called an iterator (iterator object). This iterator will have a method called next which will return an object with keys value and done like the shape below.

{ 
value: Any,
done: true|false
}
  • The value key will contain the current value. It can be of any type.
  • The done is boolean. It denotes whether all the values have been fetched or not.
Relationship between iterables, iterators, and next.

2. Generators

2.1 Definition

Generators is a new way of working with functions and iterators in the form of generator functions. A generator is a function introduced by ES6 that can stop midway and then continue from where it stopped.

A generator appears to be a function but it behaves like an iterator.

A generator is a function that produces a sequence of results instead of a single value, and returns an object on which you can call next()it will be called multiple times when iteration is performed.

2.2 Why do we need generators?

We need generators to implement iterables which enable us to loop over data structure that not iterable like object but without extra boilerplate code.

You can make sense the difference between iterators and generators in code implementing lines with this example:

— we want to make a custom iterable that returns This, is, and iterable.

Here’s one implementation using iterators :

const iterableObj = {
[Symbol.iterator]() {
let step = 0;
return {
next() {
step++;
if (step === 1) {
return { value: 'This', done: false};
} else if (step === 2) {
return { value: 'is', done: false};
} else if (step === 3) {
return { value: 'iterable.', done: false};
}
return { value: '', done: true };
}
}
},
}for (const val of iterableObj) {
console.log(val);
}// This
// is
// iterable.

Here’s the same thing using generators:

function * iterableObj() {
yield 'This';
yield 'is';
yield 'iterable.'
}for (const val of iterableObj()) {
console.log(val);
}// This
// is
// iterable.

From the above snippet code, we can conclude that generators can implement iteratble object without:

  • Symbol.iterator
  • implementing next().
  • manually make the return object of next() i.e { value: 'This', done: false }.
  • saving the state, in the iterator’s example, the state was saved in the variable step. It’s value defined what was output from the iterable. We had to do nothing of this sort in the generator.

2.3 Example

2.4 How to create generators?

For creating a generator function, we use function * syntax instead of just function. Any number of spaces can exist between the function keyword, the * .

Inside the function body, we don’t have a return. Instead, we have another keyword yield (Line 2). It’s an operator with which a generator can pause itself.

Every time a generator encounters a yield, it “returns” the value specified after it. In this case, Hello, is returned. However, we don’t say “returned” in the context of generators. We say the “the generator has yielded Hello, ”.

Generator functions return (yield) an object called an iterator (generator object). This object will have a method called next . Every invocation of next() will return an object of shape —

{ 
value: Any,
done: true|false
}
  • The value key will contain the current value. It can be of any type.
  • The done is boolean. It denotes whether all the values have been fetched or not.
Normal Functions vs Generators

Conclusion

Iterators and generators are two methods introduced by ES6 to enable us to loop over data structure that not be iterable like Object, and generators has implementing code more simple than iterators.

References

I hope this article is useful for you, thank you for your time.

--

--