How to Use a Generator Function as a Constructor
Generator function is a powerful feature of ECMAScript 2015 (aka ES6), but you cannot use it as a constructor.
function* F() {
this.a = 1;
yield this.b = 2;
yield this.c = 3;
}
new F()
// TypeError: F is not a constructor
In above code, F is a generator function. You cannot use it with new command, since F is not a constructor.
Is there a way to use it as a constructor, which means to use new command getting an instance, then use generator function’s next() method upon the instance?
I found a workaround.
First, We can use an empty object binding the this object inside generator function.
function* F() {
this.a = 1;
yield this.b = 2;
yield this.c = 3;
}var obj = {};
var f = F.call(obj);
After we call the generator function, the obj will be the instance of the generator function.
f.next(); // Object {value: 2, done: false}
f.next(); // Object {value: 3, done: false}
f.next(); // Object {value: undefined, done: true}
obj.a // 1
obj.b // 2
obj.c // 3
In above code, f is an iterator returning from F which binds obj to the inside this object. Then we call f.next() three times, since F has two yield expressions inside. After this, all instance properties will be bind to obj, so obj becomes F’s instance.
Next, I use F.prototype replacing obj, which means now we could get instance properties from f.
function* F() {
this.a = 1;
yield this.b = 2;
yield this.c = 3;
}
var f = F.call(F.prototype);
f.next(); // Object {value: 2, done: false}
f.next(); // Object {value: 3, done: false}
f.next(); // Object {value: undefined, done: true}
f.a // 1
f.b // 2
f.c // 3
The last step is wrapping F into a constructor.
function* gen() {
this.a = 1;
yield this.b = 2;
yield this.c = 3;
}
function F() {
return gen.call(gen.prototype);
}
Now we can use new upon F, and use next() upon the instance.
var f = new F();
f.next(); // Object {value: 2, done: false}
f.next(); // Object {value: 3, done: false}
f.next(); // Object {value: undefined, done: true}
f.a // 1
f.b // 2
f.c // 3
All is done. Leave your comments on Hacker News.