While trying to understand how to work with KoaJS, I came to realize that yield* undefined
behaves differently between babel & traceur. Babel seem to ignore the statement, while traceur throws an exception.
A sample can be seen here: Babel - Traceur, or below:
function* gen() {
console.log('will \'yield 1\'');
yield 1;
console.log('will \'yield undefined\'');
yield undefined;
console.log('will \'yield* undefined\'');
yield* undefined;
console.log('will \'yield 2\'');
yield 2;
}
let y = gen();
while(true) {
try {
let r = y.next();
console.log(JSON.stringify(r));
if(r.done)
break;
}
catch(e) {
console.log();
console.log(e);
console.log();
};
}
I tried looking it up in the spec and only got more confusion, since the spec for yield
doesn't look like yield undefined
is supposed to return with {done: false}
(No value property), yet that's what happens in both transpilers (also in the sample above). As for yield*
, I didn't find an answer why traceur should throw. I didn't try this with v8 (node/iojs) yet.
So the question is, what is the correct / expected behavior in both scenarios?
As you can see in the spec you reference, in the case of yield* expression
, expression
needs to have a @@iterator
property, which needs to be a method; otherwise an exception is thrown. Therefore, yield* undefined
should throw an exception because undefined
does not have the @@iterator
property.
In the case of yield undefined
, undefined
should be yielded. This is also what happens. However, in your example you evaluate JSON.stringify({value: undefined, done: false})
, which returns '{"done": false}'
because there is no such thing as undefined
in JSON.