Modified June 17, 2016.

Generators and the spread operator in JavaScript are probably two of my favorite additions, just behind `let`

, `const`

, and arrow functions. It allows for richer functions to be constructed. Here’s an overview/tutorial of what it is, and how it can be used.

Generators, if you are not already familiar, are a special type of function that are able to sequentially yield the outputs of a function. The way JavaScript generators work is that there is a main generator object, from which you can create `GeneratorFunction`

instances. You can obtain a single step of this instance using the `next`

method, which returns an object containing two key-value pairs, `value`

and `done`

. The `value`

key is what is yielded by the generator, and `done`

is a boolean saying whether or not the generator has anything left to yield. Generators are made using the `function*`

and `yield`

keywords. I’ll show you a simple generator which generates `1`

, then `2`

, then `3`

, then stops.

```
function* threeNumbers(){
yield 1;
yield 2;
yield 3;
}
```

To use this generator, assign the result of calling `threeNumbers`

to a variable, then use it’s method `next`

, like so:

```
let a = threeNumbers(); // note that we're not using `new` here
a.next(); // {value: 1, done: false}
a.next(); // {value: 2, done: false}
a.next(); // {value: 3, done: false}
a.next(); // {value: undefined, done: true}
```

This is a trivial generator, and can hardly be said to do anything useful. It is possible to create an infinite generator–any valid JS code can be used inside a generator. Each time the generator encounters `yield`

it will pause what it is doing and return a value. Once `next`

is called again, it will resume.

Generators can also take arguments. The arguments taken by generators become part of each `GeneratorFunction`

s scope. To show this, let’s look at a generator that generates multiples of a given number.

```
function* multiplesOf(num){
let counter = 0;
while(true){
yield counter;
counter += num;
}
}
let of3 = multiplesOf(3);
of3.next().value; // 0
of3.next().value; // 3
of3.next().value; // 6
of3.next().value; // 9
// ... etc.
```

`Symbol.iterator`

While generators may be interesting, you are probably wondering how they are practical. Enter `Symbol.iterator`

. An objects `Symbol.iterator`

dictates how it behaves in `for..of`

loops. Here’s a simple `Collection`

class. (Note that `*name(){...}`

in a class statement is a generator!)

```
class Collection {
constructor(){
this.vals = [];
}
get size(){
return this.vals.length;
}
retrieve(ind){
return this.vals[ind];
}
add(val){
this.vals.push(val);
}
*[Symbol.iterator](){
for(let i = 0; i < this.size; i++){
yield this.retrieve(i);
}
}
}
let a = new Collection();
a.add(5);
a.add(3);
a.add("Hi!");
for(let p of a){
console.log(p);
}
// logs:
// 5
// 3
// Hi!
```

An *iterable object* is an object for which it’s `Symbol.iterator`

is well-defined, as above. Simple! Not only is the `Symbol.iterator`

used for `for..of`

loops, it’s also used with the spread operator. The spread operator applies the yield of the iterable to a function, array, etc. For example, a string is iterable. Observe:

```
for(let i of "Hi!"){
console.log(i);
}
// logs:
// H
// i
// !
```

Thus, we can apply its members to an array, or to a function:

```
console.log([..."Hi!"]); // ["H", "i", "!"]
let f = (x, y, z) => y + z + x;
console.log(f(..."Hi!")); // "i!H"
```

What I love about the spread operator is that you can use it as a function argument operator! When used in this way, it’s called the “rest paramter”.

```
// returns it's arguments as an array
// That is, `a` contains all the arguments of the function
let f = (...a) => a;
// `b` always contains the first argument, and `a` contains the rest
// `a` is an empty array when only one argument is given.
let g = (b, ...a) => [b, a];
// however, functions like (...a, k) are not valid -- the rest parameter
// can only be used as the last argument to a function.
```

Say you have an array `A`

and a function `f`

. Here is a chart dictating some helpful results.

```
f = (a) => a; f(A) equals A
f = (...a) => a; f(A) equals [A]
f = (a) => a; f(...A) equals A[0]
f = (...a) => a; f(...A) equals A
```

While I like the rest paramter, I feel as if it could’ve been defined better. For example, there is little ambiguity when I write `(...a, b)`

–I refer to an array `a`

containing all but the last argument, which then is `b`

. The question then is what the behaviour would be when only a single argument is passed. I would say that `a`

should contain a single member, and let `b`

be undefined, though I’m sure there would be contention on this subject.

- Metaprogramming in ES6: Symbols and why they’re awesome by Keith Cirkel.
- ES6’s Unique Symbols by Vihan.