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

ale*_*ods 43 javascript ecmascript-harmony ecmascript-6

有人可以向我解释一下:为什么ES6中的发电机功能标有星号符号?

例如,而不是:

function *someGenerator() {
    yield 1;
    yield 2;
    yield 3;
}
Run Code Online (Sandbox Code Playgroud)

我们可以写:

function someGenerator() {
    yield 1;
    yield 2;
    yield 3;
}
Run Code Online (Sandbox Code Playgroud)

甚至:

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

var someObject = {

    someGenerator() {
        yield 1;
        yield 2;
        yield 3;
    }
}            
Run Code Online (Sandbox Code Playgroud)

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

为什么检测yield存在不够?

And*_*erg 55

原因有三个:

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

  2. 一般性.自然可以编写不产生的生成器,并且只能直接返回.而且,注释掉身体的一部分(例如用于调试)不应该默默地改变某些东西是否是发电机.

  3. 兼容性.只有严格的模式保留'yield'作为关键字,但是ES6的目标是所有新功能也都以草率模式提供(不幸的是恕我直言,但是).而且,即使在严格模式下,"收益率"也存在许多解析微妙之处; 例如,考虑默认参数:

    function* g(a = yield(2)) { 'use strict' }
    
    Run Code Online (Sandbox Code Playgroud)

    如果没有*,解析器只能在看到函数体之后决定如何解析yield.也就是说,你需要无限的前瞻,或回溯,或其他hacky技术来处理这个问题.

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

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

  • @alexpods,生成器方法(`{*g(){}}`)已经在ES6中了.箭头生成器不止一次被讨论过,但没有人能够提出一致且没有问题的语法. (2认同)

Ale*_* K. 7

不允许空发电机(没有车身); 那么应该unStarredFunc()遵循生成器语义吗?

出于兼容性原因:

function yield(x) { return x };

function a() { 
    yield (4+1);
};
Run Code Online (Sandbox Code Playgroud)

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

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

某些构造无法在解析时解析:

function someGenerator(i) { 
    if (glob) 
        return 4; 
    else 
        yield* anotherGen(i);
}
Run Code Online (Sandbox Code Playgroud)

当然,从function*定义中可以更容易地看出它的生成器无需深入挖掘其来源以寻找产量.