Javascript Iterators and Generators

Javascript became the most popular language in the recent decade. In addition, every day there are a bunch of updates, not only for the syntax, but also in the functional approach. For instance, the concept of using generators instead of traditional iterators. The more the updates, the more powerful your code has become. In this post, I will demonstrate how the generators are working and why it is important to get used to it.

Iterators

According to MDN documentation, iterator In JavaScript is an object that provides a next() method which returns the next item in the sequence. In the following snippet, let’s discover how the javascript work behind the scene for the normal iterator function.

createLoop execution context

What happened is that the engine reads the block line by line. Each function declaration takes place in memory as a closed box — Javascript doesn’t open that box until function invocation. Hence, constants array, i, and iterator function stored in the global memory of the global execution context. Then, when hit the return keyword the engine exit that execution context and do the following:
1. Open the child function, iterator( ), and begin a new execution context.
2. Push iterator( ) function to the call stack.

Note that by hitting return, we cannot go back to the createLoop( ) execution context — it is gone. However, iterator( ) will have access to the createLoop( ) variable array and i thanks to closure and lexical scope.

Now, iterator( ) will run as long as we invoke the iterator( ). In the example case, the iterator( ) will run twice — because we invoke the function two times only.

So, we can think of this type of iterators as a valve, only open and give the value when invoked. From performance point of view, it is like a thunderstorm change to all the future iterations.

Generators

A generator function is a special type of function that works as a factory for iterators. When it is executed it returns a new generator object. A function becomes a generator function if it uses the function* syntax MDN.

Generators provide a dynamic flow of data to us, let’s see an example.

createFlow execution context in case the inner iterator is an object

Javascript’s built-in iterators are in fact objects with a next method that when called returns the next element from the flow/collection.

Dynamic flow

Now, javascript let us make our flow more dynamic using the star *function and yield keyword.

Yield keyword is like return; however, the yield can keep you in the execution context. It runs once, and the next time when you invoke the same function, it moves on to the next yield statement. The yield has two properties, value — which returns the value, and done with boolean value — which indicates whether the function is complete or not. You can use return statement with the yield statement in the generator function, but once you hit the return statement, you exit the execution context of the generator.

By hitting return statement, you exit the generator — generator done it’s job.

The power of yield

Yield with the asterisk * can authorize it’s work to another generator. This way you can chain as many generators as you want.

Conclusion

Hope this post gives you a clear idea of what is the difference between generators and iterators. The way to implement them in your code to enhance both readability and performance. Thanks for reading!!

Data Engineer at Fortune Magazine. https://www.linkedin.com/in/salma-elshahawy/