Javascript 什么';s在ES6生成器功能中使用星号(*)的目的

Javascript 什么';s在ES6生成器功能中使用星号(*)的目的,javascript,ecmascript-6,ecmascript-harmony,Javascript,Ecmascript 6,Ecmascript Harmony,有人能给我解释一下:为什么ES6中的生成器函数用星号标记 例如,而不是: 函数*someGenerator(){ 产量1; 产量2; 产量3; } 我们可以写: 函数生成器(){ 产量1; 产量2; 产量3; } 甚至: JS编译器可以在解析时检测到someGenerator包含yield运算符,并使用此函数生成生成器 为什么检测产量是否存在还不够?不允许空发电机(无机身);那么unStarredFunc()是否应该遵循生成器语义 出于兼容性原因: function yield(x) {

有人能给我解释一下:为什么ES6中的生成器函数用星号标记

例如,而不是:

函数*someGenerator(){
产量1;
产量2;
产量3;
}
我们可以写:

函数生成器(){
产量1;
产量2;
产量3;
}
甚至:

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

为什么检测
产量
是否存在还不够?

不允许空发电机(无机身);那么
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);
}

当然,从
函数*
的定义中可以很容易地看出,它是一个生成器,无需深入其源代码来寻找收益率。

三个原因是:

  • 可读性。生成器与函数完全不同,差异应该立即可见(也就是说,不必检查整个实现以寻求收益)

  • 一般性。很自然地,应该可以编写不屈服、只直接返回的生成器。此外,注释正文的一部分(例如用于调试)不应默默地更改某个内容是否为生成器

  • 兼容性。只有strict模式保留了“yield”作为关键字,但ES6的目标是所有新功能也可以在sloppy模式下使用(IMHO做出了一个不幸的决定,但无论如何)。此外,即使在严格模式下,围绕“产量”也存在许多解析微妙之处;例如,考虑默认参数:

    function* g(a = yield(2)) { 'use strict' }
    
    如果没有
    *
    ,解析器只能在看到函数体后决定如何解析yield。也就是说,您需要无限的前瞻、回溯或其他黑客技术来处理此问题

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


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

    我对ES6了解不多,但我知道星号不是
    函数
    关键字所独有的。-您也可以使用
    yield*
    。阅读此*@JamesDonnelly是的,您可以使用
    yield*
    。所以我的问题是,为什么编译器不能通过
    yield
    (或
    yield*
    )的存在检测到函数是生成器?@limelights-我把它标了出来,但没有找到我问题的答案。你能指出答案所在的段落吗?这让我很困惑。从MDN上的文档看,星号应该是function*而不是function*。i、 它紧跟在函数本身之后,而不是函数名本身。有区别吗?1)出于兼容性原因-是的,我同意。但您可以在“严格使用”下覆盖新的实现。如果指定“使用严格”,则
    yeild
    被解释为运算符。否则,如果实现了具有此名称的函数,-
    yield
    被解释为函数,您需要在函数中添加星号
    *
    ,以使其成为生成器。回答得好。顺便说一句,即使是非空函数也可以用作生成器,其中没有
    yield
    s。在第一次调用next时,它返回
    done
    ,其中
    return
    语句的值为
    value
    .2)
    一些构造在解析时无法解析
    -实际上,您的示例是生成器,它可以在解析时解析。逻辑很简单-
    yield
    (或
    yield*
    存在)it生成器。否则——它的功能。毕竟,您无法在当前es6实现中创建条件函数/生成器函数。我接受您的观点,但检查严格性,寻找一个名为
    yield
    的现有函数(该函数随时可能存在)空发电机的特殊情况听起来比仅仅添加星号的方法要复杂得多。我认为从根本上说,
    *
    可以作为新代码中
    的保留和行为的切换,从而不会对任何现有代码造成任何问题。我想这就是为什么他们选择了以前的代码破坏符号装饰,而不是使用我想问的机会:ECMAScript委员会有没有关于数组生成器(比如
    ()*=>{}
    )和对象文本的生成器方法(比如
    var someObject={*someGenerator(){}
    )的计划?因为IMHO
    函数*
    有很多符号。如果没有数组生成器,我们必须使用
    .bind(this)
    var that=this
    ,就像在旧es5中一样。@alexpods,生成器方法(
    {*g(){}
    )已经在ES6中了。箭头生成器被讨论了不止一次,但是没有人能够想出一个一致的语法,并且没有问题。
    function* g(a = yield(2)) { 'use strict' }