javascript ES6 生成器函数中星号 (*) 的用途是什么

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27778105/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 07:58:40  来源:igfitidea点击:

What's the purpose of an asterisk (*) in ES6 generator functions

javascriptecmascript-6ecmascript-harmony

提问by alexpods

Can someone explain to me: why are generator functions in ES6 marked by asterisk symbol?

有人可以向我解释:为什么 ES6 中的生成器函数用星号标记?

For example, instead of:

例如,而不是:

function *someGenerator() {
    yield 1;
    yield 2;
    yield 3;
}

we could write:

我们可以写:

function someGenerator() {
    yield 1;
    yield 2;
    yield 3;
}

or even:

甚至:

var someGenerator = () => {
    yield 1;
    yield 2;
    yield 3;
}

var someObject = {

    someGenerator() {
        yield 1;
        yield 2;
        yield 3;
    }
}            

The JS compiler can detect that someGeneratorcontains yieldoperator at the parse time and make a generator from this function.

JS 编译器可以在解析时检测到someGenerator包含yield运算符,并从这个函数中生成一个生成器。

Why is detection of yieldexistence not enough?

为什么检测yield存在不够?

回答by Andreas Rossberg

The three reasons were:

这三个原因是:

  1. Readability. A generator is quite different from a function, and the difference should be immediately visible (that is, without examining the whole implementation in search for a yield).

  2. Generality. It should be naturally possible to write generators that do not yield, and only return directly. Moreover, commenting out part of the body (e.g. for debugging) should not silently change whether something is a generator.

  3. Compatibility. Only strict mode reserved 'yield' as a keyword, but it was made a goal for ES6 that all new features are also available in sloppy mode (an unfortunate decision IMHO, but nevertheless). Moreover, even in strict mode there are many parsing subtleties around 'yield'; for example, consider default arguments:

    function* g(a = yield(2)) { 'use strict' }
    

    Without the *, the parser could only decide how to parse the yield after it has seen the body of the function. That is, you would need infinite look-ahead, or back-tracking, or other hacky techniques to deal with this.

  1. 可读性。生成器与函数完全不同,差异应该立即可见(即,无需检查整个实现以寻找收益)。

  2. 一般性。自然应该可以编写不屈服,只直接返回的生成器。此外,注释掉主体的一部分(例如用于调试)不应该默默地改变某物是否是生成器。

  3. 兼容性。只有严格模式将 'yield' 保留为关键字,但 ES6 的目标是所有新功能也可以在 sloppy 模式下使用(恕我直言,这是一个不幸的决定,但仍然如此)。此外,即使在严格模式下,围绕“yield”也有许多解析微妙之处;例如,考虑默认参数:

    function* g(a = yield(2)) { 'use strict' }
    

    如果没有*,解析器只能在看到函数体后才能决定如何解析产量。也就是说,您需要无限前瞻、回溯或其他黑客技术来处理这个问题。

I should note that (1) and (2) are already reason enough.

我应该注意到(1)和(2)已经足够了。

(Full disclosure: I am a member of the EcmaScript committee.)

(完全披露:我是 EcmaScript 委员会的成员。)

回答by Alex K.

Empty generators (with no body) are not disallowed; so should unStarredFunc()follow generator semantics or not?

不允许使用空生成器(没有主体);那么是否应该unStarredFunc()遵循生成器语义?

For compatibility reasons:

出于兼容性原因:

function yield(x) { return x };

function a() { 
    yield (4+1);
};

this is syntactically correct but calling .next()would result in an error whereas adding an asterisk to explicitly define a generator would cause .next().value === 5

这在语法上是正确的,但调用.next()会导致错误,而添加星号来显式定义生成器会导致.next().value === 5

detect that someGenerator contains yield operator at parse time

在解析时检测 someGenerator 包含 yield 运算符

Some constructs cannot be resolved at parse time:

一些结构在解析时无法解析:

function someGenerator(i) { 
    if (glob) 
        return 4; 
    else 
        yield* anotherGen(i);
}

And of course its simpler to see immediately from the function*definition that its a generator without needing to dig into its source to look for yields.

当然,从function*定义中立即可以更简单地看出它是一个生成器,而无需深入研究其来源以寻找产量。