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

时间:2015-01-05 10:58:50

标签: javascript ecmascript-6 ecmascript-harmony

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

例如,而不是:

function *someGenerator() {
    yield 1;
    yield 2;
    yield 3;
}
我们可以写:

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

甚至:

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

var someObject = {

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

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

为什么检测yield存在不够?

2 个答案:

答案 0 :(得分:55)

原因有三:

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

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

  3. 兼容性。只保留严格模式' yield'作为关键字,但ES6的目标是所有新功能也以草率模式提供(不幸的决定恕我直言,但不过)。而且,即使在严格的模式下,也会有很多解析的细微差别在于' yield&#39 ;;例如,考虑默认参数:

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

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

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

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

答案 1 :(得分:7)

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

出于兼容性原因:

function yield(x) { return x };

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

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

  

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

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

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

当然,从function*定义中直接看到它的生成器更简单,不需要深入研究其来源以寻找产量。