yield and new : SpiderMonkey and the draft Spec

Brendan Eich brendan at mozilla.com
Mon Mar 14 06:51:30 PDT 2011


On Mar 14, 2011, at 3:02 AM, Dmitry Soshnikov wrote:

> Yep, thanks Brendan,
> 
> I filed the bug https://bugzilla.mozilla.org/show_bug.cgi?id=641436
> 
> But the thing with `this` is still interesting for me. So in this particular case `this` should be set to `undefined`.

No, |this| is not set to undefined. The generator function yields undefined each time (via |yield;| in the loop body).

That undefined is what the anonymous expression closure you pass to map should (absent the bug) return in turn (i.e., undefined is the return value of g.next() and thus the return value of function(i) g.next()).

Notice how you evaluate a |new| operator exactly once, in the top-level assignment expression statement:

>> // infinite objects generator
>> let g = new function () {
>>  this.x = 10;
>>  while (true) {
>>    yield;
>>  }
>> };
>> 
>> // generate an array of 3 objects
>> let objects = [1, 2, 3].map(function(i) g.next());

A generator function called as a constructor via new receives a fresh Object instance as |this|, same as for any function.

However, there's no way for a generator function to return that instance, because a generator function always implicitly returns a fresh generator iterator when invoked. It could store |this| in the heap, and whatever value |this| receives is saved as part of the shallow continuation capture by the generator.

If you write |return this| anywhere in the body of the generator function you'll get an early error. So really all |new| is doing for you here is giving a fresh object to |this|, which seems fine if that's what you want.

/be



More information about the es-discuss mailing list