for 循环中的函数生成器

leo*_*fed 4 javascript for-loop generator

我试图更好地理解生成器在 javascript 中的工作原理。

来自 MDN:

function* 声明(function 关键字后跟星号)定义一个生成器函数,该函数返回一个 Generator 对象。

function *range(from, to) {
    var counter = from;
    while(to >= counter) {
        yield counter
        counter++
    }        
}

for (var r of range(5, 10)) {
    console.log( r );
}

// print: 5, 6, 7, 8, 9, 10
Run Code Online (Sandbox Code Playgroud)

我不确定我如何准确理解上面代码片段中发生的事情。

生成器不是应该被调用、存储为(生成器)对象然后由next()方法调用吗?(如下所示)

function *foo () {
      yield 'woo';
 }
 var G = foo();
 console.log( G.next() );
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,在第 4 行,var G = foo();没有调用函数并创建新的执行上下文,这应该只返回一个生成器对象(并将其存储在标签下G)。

foo当我在第 5 行调用该方法时,我将调用实际的函数next()。此时,我将创建一个执行上下文,执行内部代码foo并生成字符串"woo"

第一个片段究竟应该如何工作?

Cer*_*nce 5

调用生成器函数将返回一个迭代器(带有函数的对象.next),并且for..of循环将自动迭代可迭代对象。虽然您可以预先将迭代器存储在变量中:

const iter = range(5, 10);
for (var r of iter) {
  ...
}
Run Code Online (Sandbox Code Playgroud)

这是没有必要的——for..of毕竟只需要对迭代器的单个引用。

您可以在代码中模仿这一点,将对迭代器的单个引用传递到调用每个.next函数的函数中,直到迭代器耗尽为止:

const iter = range(5, 10);
for (var r of iter) {
  ...
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,在将迭代器传递给 之前,无需将迭代器存储在变量中iterate,就像您可以range(5, 10)直接使用循环调用一样for..of,因为循环(或函数)的内部结构会为您完成所有迭代。