Conor O'Brien
Conor O'Brien

Reputation: 1037

Modifying generator function prototype

TL;DR

I want to modify the prototype of a generator function instance--that is, the object returned from calling a function*.


Let's say I have a generator function:

function* thing(n){
    while(--n>=0) yield n;
}

Then, I make an instance of it:

let four = thing(4);

I want to define a prototype of generators called exhaust, like so:

four.exhaust(item => console.log(item));

which would produce:

3
2
1
0

I can hack it by doing this:

(function*(){})().constructor.prototype.exhaust = function(callback){
    let ret = this.next();
    while(!ret.done){
        callback(ret.value);
        ret = this.next();
    }
}

However, (function*(){})().constructor.prototype.exhaust seems very... hacky. There is no GeneratorFunction whose prototype I can readily edit... or is there? Is there a better way to do this?

Upvotes: 7

Views: 997

Answers (1)

Bergi
Bergi

Reputation: 665584

There is no GeneratorFunction whose prototype I can readily edit... or is there?

No, GeneratorFunction and Generator do not have global names indeed.

If you want to modify them… Don't. Extending builtins is an antipattern. Write a utility module of static helper functions.

(function*(){})().constructor.prototype seems very... hacky. Is there a better way to do this?

I would recommend

const Generator = Object.getPrototypeOf(function* () {});
const GeneratorFunction = Generator.constructor;

then you can do

Generator.prototype.exhaust = function(…) { … };

if you really need to. But remember, if you just want to extend the generators created by function* thing then you can also do

thing.prototype.exhaust = …;

which is probably a better idea.

Upvotes: 7

Related Questions