JavaScript 中的“函数*”是什么?

IT技术 javascript function ecmascript-6
2021-01-20 00:58:13

这个页面中,我发现了一个新的 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不要费心尝试谷歌,用星号搜索表达式不可能的它们被用作占位符)。

4个回答

这是一个生成器函数。

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

调用生成器函数不会立即执行其主体;而是返回该函数的迭代器对象。当迭代器的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
跟进:没有参数 ( for(;;))的 for 循环有什么作用?为什么在这种情况下使用它?
2021-03-16 00:58:13
@Fergie,for(;;)while (true). 它在此上下文中使用,因为斐波那契数列是一个无界数列。
2021-03-28 00:58:13
@DaveVandenEynde,现有技术:Python 产量。在先现有技术:CLU 和 Icon。
2021-04-05 00:58:13

这是一个生成器函数- 它在您引用的页面中如此说,在您用“这是有趣的行”替换的评论中......

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

“通过索引访问而无需计算整个序列”可能是迄今为止我遇到的关于生成器的最有用的解释。我可以看到在应用程序中使用它,而以前只是从理论上理解它。
2021-03-17 00:58:13

function*类型看起来像是可以迭代的进程的生成器函数。C# 有一个这样的特性,使用“收益回报”见 1见 2

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

恢复它的简单示例

这是一个函数生成器,见下面的例子
function* generator(i) {
  yield i;
  yield i + 10;
}

const gen = generator(10);

console.log(gen.next().value);
// expected output: 10

console.log(gen.next().value);
// expected output: 20

文档:MDN