ES6 中 "yield* undefined" 和 "yield undefined" 的正确(规范)行为是什么?

What is the correct (spec-wise) behavior of "yield* undefined" & "yield undefined" in ES6?

在尝试了解如何使用 KoaJS 时,我开始意识到 yield* undefined 在 babel 和 traceur 之间的行为不同。 Babel 似乎忽略了声明,而 traceur 抛出了异常。 可以在此处查看示例:Babel - Traceur,或下方:

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();
  };
}

我试着在 spec 中查找它,结果更加混乱,因为 yield 的规范看起来 yield undefined 不应该 return使用 {done: false}(无值 属性),但这就是两个转译器(也在上面的示例中)发生的情况。至于yield*,我没有找到traceur为什么要抛出的答案。我还没有用 v8 (node/iojs) 尝试这个。

所以问题是,两种情况下的正确/预期行为是什么?

正如您在引用的规范中看到的那样,在 yield* expressionexpression needs to have a @@iterator property 的情况下,这需要是一个方法;否则抛出异常。因此,yield* undefined 应该抛出异常,因为 undefined 没有 @@iterator 属性.

yield undefined的情况下,应该产生undefined。这也是发生的事情。但是,在您的示例中,您评估了 JSON.stringify({value: undefined, done: false}),其中 returns '{"done": false}' 因为 JSON.

中没有 undefined 这样的东西