什么是JavaScript中的"function*"?

str*_*QNA 239 javascript function ecmascript-6

这个页面中,我找到了一个新的JavaScript函数类型:

// NOTE: "function*" is not supported yet in Firefox.
// Remove the asterisk in order for this code to work in Firefox 13 

function* fibonacci() { // !!! this is the interesting line !!!
    let [prev, curr] = [0, 1];
    for (;;) {
        [prev, curr] = [curr, prev + curr];
        yield curr;
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经知道了什么yield,let以及[?,?]=[?,?]做的,但不知道什么function*是注定的.它是什么?

PS不打扰尝试谷歌,用星号搜索表达式是不可能的(它们被用作占位符).

Mik*_*uel 193

这是一个发电机功能.

生成器是可以退出并稍后重新输入的功能.他们的上下文(变量绑定)将在重新入口处保存.

调用生成器函数不会立即执行其正文; 而是返回该函数的迭代器对象.当next()调用迭代器的方法时,执行生成器函数的主体直到第一个yield表达式,该表达式指定从迭代器返回的值,或者yield*委托给另一个生成器函数.


历史记录:

这是一个提议的语法EcmaScript.next.

Mozilla的Dave Herman发表了关于EcmaScript.next的演讲.在30:15他谈论发电机.

之前,他解释了Mozilla如何通过实验实施提议的语言变更来帮助指导委员会.Dave与Mozilla的首席技术官(我认为)和最初的JavaScript设计师Brendan Eich密切合作.

您可以在EcmaScript工作组wiki上找到更多详细信息:http://wiki.ecmascript.org/doku.php?id = eth:generator

工作组(TC-39)普遍同意EcmaScript.next应该有某种生成器迭代器提议,但这不是最终的.

你不应该依赖于这种显示而不改变下一版本的语言,即使它没有改变,它也可能暂时不会在其他浏览器中出现.

概观

第一类协同程序,表示为封装挂起的执行上下文(即函数激活)的对象.现有技术:Python,Icon,Lua,Scheme,Smalltalk.

例子

Fibonacci数的"无限"序列(尽管行为约为2 53):

function* fibonacci() {
    let [prev, curr] = [0, 1];
    for (;;) {
        [prev, curr] = [curr, prev + curr];
        yield curr;
    }
}
Run Code Online (Sandbox Code Playgroud)

生成器可以在循环中迭代:

for (n of fibonacci()) {
    // truncate the sequence at 1000
    if (n > 1000)
        break;
    print(n);
}
Run Code Online (Sandbox Code Playgroud)

生成器是迭代器:

let seq = fibonacci();
print(seq.next()); // 1
print(seq.next()); // 2
print(seq.next()); // 3
print(seq.next()); // 5
print(seq.next()); // 8
Run Code Online (Sandbox Code Playgroud)

  • @Fergie,`for(;;)`与`while(true)`相同.由于Fibonacci序列是无界序列,因此在此上下文中使用它. (13认同)
  • 跟进:没有参数的for循环(`for(;;)`)有什么作用?为什么在这种情况下使用它? (7认同)
  • 现有技术:C#产量? (5认同)
  • @DaveVandenEynde,先前的现有技术:Python产量.先前的现有技术:CLU和Icon. (3认同)

Mic*_*rdt 51

它是一个生成器函数 - 它在您引用的页面中这样说,在您用"这是有趣的行"替换的注释中......

基本上,它是一种以编程方式指定序列的方法,以便可以传递它们并通过索引访问元素,而无需事先计算整个序列(可能是无限大小).

  • "通过索引访问而不必计算整个序列"可能是迄今为止我遇到的关于生成器的最有用的解释.我可以在一个应用程序中看到使用它,而以前只是在理论上理解它. (10认同)

小智 11

function*类型看起来像充当可以迭代的进程的生成器函数.C#有这样的功能,使用"yield return" 参见1,见2

本质上,这将逐个返回每个值到迭代此函数的任何值,这就是为什么它们的用例在foreach样式循环中显示它的原因.