JavaScript中的“功能*”是什么?


243

页面中,我找到了新的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;
    }
}

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

PS不会尝试使用Google,因为搜索带有星号的表达式是不可能的它们被用作占位符)。


4
示例中的注释现在已经很老了,function*自v26起,Firefox支持语法:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…*。较旧的版本使用了不同的语法。
Nickolay 2014年

39
对于Google,只需搜索“功能星号”或“功能星号”。这就是我发现这个问题的方式;)。
trysis'2

2
似乎*已将其从@Nickolay的链接中删除。这是直接指向function*MDN的链接。自v26以来,肯定有“基本”支持。
鲁芬,2015年

另一个MDN链接(其中,顺便说一句,我的MDN页面通过OP链接上找到)developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
丹尼Pflughoeft - BlueRaja

Answers:


199

这是一个生成器功能。

生成器是可以退出并随后重新输入的函数。它们的上下文(变量绑定)将在重入时保存。

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


历史记录:

这是的建议语法EcmaScript.next

Mozilla的Dave Herman谈到了EcmaScript.next。在30:15他谈到了发电机。

之前,他解释了Mozilla如何通过实验方式实施建议的语言更改以帮助指导委员会。Dave与Mozilla的CTO(我认为)和原始JavaScript设计师Brendan Eich紧密合作。

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

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

如果不更改该语言的下一个版本,则不应依靠它来显示,即使它没有变化,也有一段时间不会在其他浏览器中广泛显示。

总览

一流的协程,表示为封装暂停执行上下文(即函数激活)的对象。现有技术:Python,Icon,Lua,Scheme,Smalltalk。

例子

斐波纳契数的“无限”序列(尽管行为在2 53附近):

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

生成器可以循环迭代:

for (n of fibonacci()) {
    // truncate the sequence at 1000
    if (n > 1000)
        break;
    print(n);
}

生成器是迭代器:

let seq = fibonacci();
print(seq.next()); // 1
print(seq.next()); // 2
print(seq.next()); // 3
print(seq.next()); // 5
print(seq.next()); // 8

7
跟进:没有参数的for循环(for(;;))有什么作用?为什么在这种情况下使用它?
Fergie

13
@Fergie for(;;)与相同while (true)。由于斐波那契数列是一个无界序列,因此在此上下文中使用它。
Mike Samuel

5
现有技术:C#产量?
Dave Van den Eynde 2014年

3
@DaveVandenEynde,现有技术:Python产出。现有技术现有技术:CLU和Icon。
Mike Samuel

52

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

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


10
“到目前为止,我无需再计算整个序列就可以通过索引访问”,这可能是我迄今为止遇到的有关生成器的最有用的解释。我可以看到在应用程序中使用了它,而以前只是从理论上了解它。
2015年

11

function*类型看起来像是可迭代进程的生成器函数。C#具有这样的功能,使用“收益率回报” 参见12

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.