Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 313
Conor O'Brien Avatar asked Jul 26 '16 02:07

Conor O'Brien


People also ask

How do you write a function prototype?

A function prototype begins with the keyword function, then lists the function name, its parameters (if any), and return value (if any). The prototype includes no executable code. You can use function prototypes in the following situations: When defining an ExternalType (see ExternalType part).

Do functions have a prototype?

Every function has the "prototype" property even if we don't supply it. The default "prototype" is an object with the only property constructor that points back to the function itself. We can use constructor property to create a new object using the same constructor as the existing one.

What is the purpose of the [[ prototype ]] property of objects?

The answer is Prototype. The prototype is an object that is associated with every functions and objects by default in JavaScript, where function's prototype property is accessible and modifiable and object's prototype property (aka attribute) is not visible. Every function includes prototype object by default.

What is .next in JavaScript?

Next.js is a flexible React framework that gives you building blocks to create fast web applications.


1 Answers

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.

like image 61
Bergi Avatar answered Oct 04 '22 07:10

Bergi