# JS Tip of the Day: Generator Prototypes

**URL:** <https://forum.kirupa.com/t/js-tip-of-the-day-generator-prototypes/643106>\
**Category:** web dev\
**Created:** [April 30, 2020, 3:07pm UTC](https://forum.kirupa.com/t/js-tip-of-the-day-generator-prototypes/643106 "2020-04-30T15:07:22Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![senocular](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/senocular/32/7217_2.png) [@senocular](https://forum.kirupa.com/u/senocular)\
**Post date:** [April 30, 2020, 3:07pm UTC](https://forum.kirupa.com/t/js-tip-of-the-day-generator-prototypes/643106/1 "2020-04-30T15:07:22Z")

</div>

**Generator Prototypes**  
Version: ES2015  
Level: Advanced

Most functions that can’t be constructors also don’t have `prototype` properties. Generator functions are different. Though they too can’t be constructors, they still have a `prototype`.

```javascript
let arrow = () => {}
console.log(typeof arrow.prototype); // undefined

let obj = { method () {} };
console.log(typeof obj.method.prototype); // undefined

function * gen () {}
console.log(typeof gen.prototype); // object

```

This is because, while not constructors, they are factory functions that create new generator objects whenever they’re called. The generator objects returned from a generator function will have prototypes set to the `prototype` of the generator function.

```javascript
function * gen () {}
let iter = gen();
console.log(Object.getPrototypeOf(iter) === gen.prototype); // true

```

This provides an opportunity to give your generator objects custom methods by defining them in the generator function’s `prototype`.

```javascript
function * countTo (count) {
    for (let i = 1; i <= count; i ++) {
        yield i;
    }
}

```

```javascript
countTo.prototype.evens = function () {
    return {
        next: (...args) => {
            let result;
            do {
                result = this.next(...args);
            } while (!result.done && result.value % 2 === 1);
            return result;
        },
        return: this.return.bind(this),
        throw: this.throw.bind(this),
        [Symbol.iterator] () {
            return this;
        }
    };
}

```

```javascript
for (let num of countTo(4)) {
    console.log(num); // 1 2 3 4
}
for (let num of countTo(4).evens()) {
    console.log(num); // 2 4
}

```

Here an `evens()` method is added to the `countTo` generator that creates a new iterator/iterable object that reads the `next()` iterator results from the original generator object and then only provides them as iterator results from itself if the value is even. In addition, it forwards any calls it gets for `return()` and `throw()` to the original iterator.

Creating a generator method like `evens()` can be difficult. The way it works as a wrapper for the original iterator can be awkward, especially in having to make sure methods like `return()` and `throw()` are forwarded. Additionally, you’re left out of being able to chain further unless `evens()` provided additional methods of its own because as an iterator object and not a generator from `countTo()`, it doesn’t inherit any other methods that may have been defined within `countTo.prototype`. As such, it’d be uncommon for anyone to make generator methods this way and I wouldn’t recommend you start doing so yourself.

That said, there is a new proposal that adds new methods to iterators that would work much like `evens()` above. Generator objects would inherently have access to methods like `map()`, `filter()`, etc. for modifying the output of the generator results during iteration. For more information see the Iterator Helpers link below.

More info:

- [Generator on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator)
- [Proposal: Iterator Helpers](https://github.com/tc39/proposal-iterator-helpers)
