# JavaScript: Generator Functions

There is such a thing as generator functions in JavaScript and they let you define functions that return Generator objects. The syntax for defining a generator function is nearly the same as for defining a regular function.

```javascript
function* makeIterator() {
    yield 1
}
```

Note the use of `function*` (the added asterisk) and the `yield` keyword. Calling `makeIterator()` will return a Generator object. Generator objects are iterable objects similar to Array and Map objects. They can be looped over easily using the `for ... of` syntax, for example.

> Iterating over an iterator is said to consume the iterator because it is generally only possible to do once. - MDN

### More Examples

In this example, the defined generator function allows for defining ranges. Calling the Generator object's `next()` function returns an object with two properties: `value` and `done`.

```javascript
function* range(start, end) {
  for (let i = start; i <= end; i++) {
    yield i;
  }
}

let myRange = range(1, 3)
console.log(myRange.next()) // { value: 1, done: false }
console.log(myRange.next()) // { value: 2, done: false }
console.log(myRange.next()) // { value: 3, done: false }
console.log(myRange.next()) // { value: undefined, done: true}
```

The range can be immense (even Infinity) but won't allocate space for every value that the range represents. Also, the generator is lazily evaluated - meaning there is no execution cost if the values are never needed.

```javascript
// These have identical memory and execution costs.
let rangeA = range(1, 3)
let rangeB = range(1, Infinity)
```

### Use Cases

There are probably many amazing use cases for generators. But one that interests me specifically is generating repeating reminders/scheduled events that potentially continue indefinitely.
