lewisdale.dev/src/blog/posts/2015/2/using-es6-generators.md
2023-12-26 14:35:09 +00:00

82 lines
2.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: "Using ES6 Generators"
date: 2015-02-26T00:00:00
slug: using-es6-generators
---
Ive been having fun using some newer technology recently - namely ECMAScript 6 Harmony (or at least the bits of it that Chrome supports). One particular feature which Ive been using has made life quite a lot easier for me - ES6 now supports Generator functions, and they can be used to implement iteration with objects.
## What Are Generators?
If youve never used them before, a Generator is a function that can be used as an iterator - I.E. you can use them in a for-each loop, much like you would an array. The difference between using a Generator and a function that returns an Iterable (e.g. an Array), is the Yield keyword, which acts like a return statement except that it returns the next iterable value.
This means that we dont have to have a list of the objects we want to iterate over, the list can be built as you iterate, meaning you only use as much memory as necessary for the loop, instead of the maximum amount needed to store the entire data structure.
Sometimes there are no apparent benefits to using Generators, but if you find yourself traversing a data structure repeatedly, youre going to have a lot of repeated code, and using Generators can save you the hassle of repeating yourself.
Generators arent unique to ECMAScript - they can be found in many languages. Read about using them in Python [here](https://blog.assemblyco.de/optimising-the-fibonacci-sequence-with-generators/).
## Using Generators
A Generator function is noted by `function*`:
```javascript
function* myGenerator() {
yield 1;
yield 2;
yield 3;
}
```
We can either use our Generator as an object:
```javascript
var gen = new myGenerator();
console.log(gen.next()); //1
console.log(gen.next()); //2
console.log(gen.next()); //3
```
Or access it as a function:
```javascript
for(var x of myGenerator()) {
console.log(x);
}
>> 1
>> 2
>> 3
```
But thats not much good to us! We want to be able to overwrite an Objects `Symbol.iterator`, so that we can iterate the object directly.
```javascript
function IterableObj() {
this.data = [1,2,3,4,5,6,7,8,9,10,11,12]
}
IterableObj.prototype[Symbol.iterator] = function* () {
for(var x of this.data) {
yield x * 4;
}
}
var myObj = new IterableObj();
for(var data of myObj) {
console.log(data);
}
>> 4
>> 8
>> 12
>> 16
>> ...
```
So those are the basics of using ES6 Generators. Check out some of the links below for further reading!
* [Iteration Protocols - Javascript MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols)
* [function* - Javascript MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*)