es6中yield和yield*有什么区别?

一个*号的区别吗?

阅读 11.2k
2 个回答

两者都是返回 iterator 的一个元素,不过

yield 的返回值是当作一个元素
yield* 的返回值是一个 iterator,会依次返回这个 iterator 中的每个元素

举例

function* sub() {
    for (let i = 65; i < 70; i++) {
        yield String.fromCharCode(i);
    }
}

function* main() {
    yield "begin";
    yield sub();    // 返回的是 sub() 的结果,一个对象
    yield "---------";
    yield* sub();   // 依次返回 sub() 结果的的每一项
    yield "end";
}

for (var v of main()) {
    console.log(v);
}

clipboard.png


「2021-01-24」补充

@alanhg

Generator 函数返回的是一个 Generator 对象,我们主要使用它的 next() 方法来判断是否有值,以及值是什么,它的返回值结构是:{ value, done }

来看个示例:

function* test1() {
    yield 1;
    yield 2;
}

function* test2() {
    yield 1;
    return 2;
}

const x1 = test1();
console.log("x1", x1.next());
console.log("x1", x1.next());
console.log("x1", x1.next());

const x2 = test2();
console.log("x2", x2.next());
console.log("x2", x2.next());
console.log("x2", x2.next());

输出

x1 { value: 1, done: false }
x1 { value: 2, done: false }   <-- 注意这里
x1 { value: undefined, done: true }
x2 { value: 1, done: false }
x2 { value: 2, done: true }    <-- 注意这里
x2 { value: undefined, done: true }

注意 yieldreturn 都可以在 next().value 中把值带出来,他们的区别在于 yield 对应的 next().donefalse,而 return 对应的 next().donetrue

对于之后(每种情况第 3 项),都再没有返回值,所以 value 都是 undefined,也都没有对应的 yield 语句,所以 donetrue(可以这样理解,函数自然完成,相当于是在最后 return,而 returnreturn undefined 是等价的。

for ... of 大概可以翻译成这样一个 while

const x = test1();
let next;
while (next = x.next(), !next.done) {
    console.log(next);
}

一旦 done 就跳出循环,所以 return 产生的 next().value 不会被循环体处理。(要不然,对于标准的,只有 yield 的 generator,最后会在循环体里处理一个 undefined

以上是「2021-01-24」补充

The yield keyword is used to pause and resume a generator function.
The yield* expression is used to delegate to another generator or iterable object.

function* g1() {
  yield 2
  yield 3
}

function* g2() {
  yield 1
  yield g1()
  yield* g1()
  yield [4, 5]
  yield* [6, 7]
}

const iterator = g2()

console.log(iterator.next()) // { value: 1, done: false }
console.log(iterator.next()) // { value: {}, done: false }
console.log(iterator.next()) // { value: 2, done: false }
console.log(iterator.next()) // { value: 3, done: false }
console.log(iterator.next()) // { value: [4, 5], done: false }
console.log(iterator.next()) // { value: 6, done: false }
console.log(iterator.next()) // { value: 7, done: false }
console.log(iterator.next()) // { value: undefined, done: true }
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏