我可以在生成器中使用ES6的arrow函数语法吗?(箭头符号)


242

即我如何表达这一点:

function *(next) {}

与箭头。我已经尝试了所有可以想到的组合,但是找不到任何文档。

(当前使用节点v0.11.14)


5
你不能 抱歉。“该function*语句(function关键字后跟一个星号)定义了一个生成器函数。”

2
请注意,在esdiscuss.org上对此主题进行了冗长的讨论。
voithos 2014年

4
您期望param*=>{ }做什么?
CoderPi

4
你知道那function(){}不一样()=>{}吗?
CoderPi

8
ES6生成器真的向前2步,然后向后1步吗? ”-不,生成器只能向前前进:-)
Bergi 2015年

Answers:


229

我可以在生成器中使用ES6的arrow函数语法吗?

你不能 抱歉。

根据MDN

function*声明(function关键字后跟一个星号)定义的发电机的功能。

规格文件中(我的重点):

函数的语法扩展到添加一个可选的*令牌:

FunctionDeclaration: "function" "*"? Identifier "(" FormalParameterList? ")" 
  "{" FunctionBody "}"

172
对我来说感觉像是设计缺陷。
乔纳森2015年

23
@乔纳森:没有。箭头函数应该是轻量级的(.prototype例如没有),通常是单线的,而生成器则相反。
Bergi 2015年

38
我已经遇到过几种情况,其中我正在玩的生成器需要访问上一个this,并且不得不编写let self = thishack才能在生成器中访问它。词汇范围+箭头语法会很好。不幸的是,但并非世界末日。
dvlsg 2015年


20
@Bergi箭头功能背后的推理要复杂得多。并不是很简洁。箭头函数不必是轻量级的-的确有一个可选的单语句主体语法,但是该怎么办。许多人使用箭头表示除类方法之外的所有函数定义,并将function关键字降级为该语言的“不良部分”。有充分的理由执行此操作。对于这些人来说,缺少箭头生成器是一个令人烦恼的矛盾之处。
callum

130

内联功能和箭头功能之间的区别

首先,箭头功能 () => {}不能替代内联功能function(){},它们是不同的。内联函数只是简单的函数,因此问题是箭头函数和内联函数之间的区别是什么。

相比函数表达式的箭头函数表达式(也称为箭头功能)具有较短的语法,并且不结合其自身的thisargumentssuper,或new.target)。箭头函数始终是匿名的。

一些更快速的细节在这里


为什么箭头功能不能用作生成器

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions

使用yield关键字

产率的关键字可能无法在箭头函数体中使用(除了当进一步嵌套在功能在允许范围内)。因此,箭头函数不能用作生成器。

请注意,没有生成器没有yield意义。


为什么箭头功能不能使用yield

http://tc39wiki.calculist.org/es6/arrow-functions/

箭头函数按this词法进行绑定,return在“ 体”情况下进行绑定,以便它从紧接的箭头函数返回,breakcontinue从紧接的箭头函数外部进行引用和引用。

标识符初级表达arguments可能无法在箭头函数体被使用(是否表达或块形式)。

同样,yield不能在箭头函数的主体中使用。箭不能成为发生器,我们不希望深入延续。

箭头函数的产量会引发语义错误:http : //www.ecma-international.org/

最后,原因在于ECMA6的实施非常复杂。由于某些类似的原因, C#也不允许这样做。


3
我使用了搜索引擎,并为您发布了另一本说明
CoderPi

1
我仍然认为,添加有关的解释()=>{}将大有帮助,了解其与内联函数的区别以及为什么生成器存在局限性。
vitaly-t 2015年

63
我试图弄清楚为什么*() => { yield bla; }不行,但是async () => { await bla; }...
Lee Benson

7
@CodeiSir,关于“ ,我们不想深入延续 ”,糟糕的借口。
Pacerier's

9
您的论点是周期性的。您说箭头函数不能是生成器,因为它们中不能包含yield关键字。但是它们不能使用yield关键字,因为它们不能成为生成器:“箭头不能是生成器,我们不希望深度延续。”
Thayne

35

除了上述关于esdiscuss.org的讨论以及Ecma TC39委员会ES6会议笔记(从2013年11月起)之外,在2016年9月的两次ES7会议中再次讨论了生成器箭头[1] [2]。在讨论了各种语法(主要是=*>=>*)的利弊以及缺乏针对该功能的理由和用例之后,他们得出以下结论:

  • 委员会有一些兴趣,但担心该功能不会增加添加新语法的作用
  • 计划=>*在[Domenic Denicola]异步迭代提案的一部分,在第3天重新进行考察,看看是否至少可以进入阶段0

关于发电机箭头的提议已由Brendan Eich和Domenic Denicola作为冠军进入了第一阶段。上述异步迭代已于2018年完成并实现

在2019年10月,谢尔盖·鲁巴诺夫(Sergey Rubanov)的官方仓库出现了,有关语法和其他细节的更多讨论。


8

我也有同样的问题,来到这里。阅读帖子和评论后,我觉得在箭头函数中使用generator似乎比较模糊:

const generator = () => 2*3; // * implies multiplication
// so, this would be a confusing
const generator = () =>* something; // err, multiplying?
const generator = () =*> ... // err, ^^
const generator = ()*=> ... // err, *=3, still multiplying?
const generator=*()=> ... // err, ^^
const generator = *param => ... //err, "param" is not fixed word

这可能是他们没有实现与箭头功能相关的生成器的主要原因。


但是,如果我是其中之一,我可能会这样想:

const generator = gen param => ... // hmm, gen indicates a generator
const generator = gen () => ... // ^^

感觉就像我们有异步功能:

const asyncFunction = async () => ... // pretty cool

因为正常功能中存在async关键字,所以箭头功能正在利用它- async () =>似乎很可能async function()

但是,没有像gen或这样的关键字,generator而且箭头功能未使用它。

结论:

即使他们希望在arrow函数中实现生成器,我认为他们也需要重新考虑核心js中的生成器语法:

generator function myfunc() {}
// rather than
function* myfunc() {} // or, function *myfunc() {}

这将是一个大错误。因此,将箭头功能保持在生成器之外非常酷。


以下@Bergi评论

不能。箭头函数应该是轻量级的(例如,没有.prototype),并且通常是单行的,而生成器则相反。

我会说生成器的使用目的是运行-停止-运行,因此,我认为我们不需要关心原型,词法分析等等。


2
也可以考虑异国情调的选择,例如() ~> { yield 'a'; yield 'b'; }。老实说,我只是喜欢波浪号。
Gershom

@Gershom这就是像Perl这样的编程语言完全出错的方式
Sapphire_Brick

2

我知道这已经很晚了,但是另一个可能的原因可能是语法。也许(*() => {})可行,但是那又如何(9 ** () => {})呢?这是9的箭头功能的幂返回NaN还是9倍的生成器箭头功能的返回NaN?可以使用一些其他语法来完成它,如此处=>*的另一个答案所提到的那样,但是可能希望在实现时保持生成器函数语法(例如function* () {}{ *genMethod() {} })的一致性。不是太多的借口,而是这样做的原因。


1
:+1:双星号...老学校的JS家伙在这里。谁说你不能教老狗新的花样:欢乐:
Shanimal

他们不这样做的唯一原因是因为使解析器变得困难。这是完全可能的,不需要在语法上做出妥协。
詹森·麦卡雷尔

@JasonMcCarrell如果他们足够关心不使解析器过于复杂,那么也许Brendan Eich应该将Scheme放在浏览器中。
Sapphire_Brick


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.