我可以使用ES6's箭头函数语法生成器?(箭头符号)

也就是说,我怎么表达

function *(next) {}

用箭头语法?我已经尝试了所有我能想到的组合,但我找不到任何关于它的文档。

(我目前使用的是Node.js v0.11.14。)

112490 次浏览

我可以使用ES6的箭头函数语法生成器吗?

你不能。对不起。

根据中数

function*语句(function关键字后面带星号)定义了一个生成器函数。

来自规范文档(我的重点):

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

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

内联函数和箭头函数的区别

首先,Arrow-functions () => {}不是用来替换内联函数function(){},它们是不同的。 内联函数就是简单的函数,所以问题是箭头函数和内联函数之间的区别是什么

与函数表达式相比,箭头函数表达式(也称为箭头函数)具有更短的语法,并且不绑定自己的thisargumentssupernew.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也不能在箭头函数体中使用。箭头不能作为生成器,我们也不想要深度延续。

Yield在一个箭头函数将抛出语义错误:http://www.ecma-international.org/

究其原因,在于ECMA6实现的深度复杂性。c#也不允许类似的原因

除了上面提到的esdiscuss.org2013年11月Ecma TC39委员会ES6会议记录的讨论之外,生成器箭头在2016年9月的两次ES7会议[1] [2]中被重新讨论。在讨论了各种语法(主要是=*>=>*)的优缺点以及缺乏该特性的理由和用例之后,他们得出了这样的结论:

  • 委员会对此有一些兴趣,但担心该特性在添加新语法方面没有发挥应有的作用
  • 计划在第三天重新审视,看看我们是否能把=>*至少带到阶段0,作为[Domenic Denicola]的异步迭代提案的一部分

生成器箭头的提议被移到阶段1, Brendan Eich和Domenic Denicola作为冠军。上面提到的异步迭代在2018年是完成并实施

2019年10月,谢尔盖·鲁巴诺夫的官方回购的出现引发了更多关于语法和其他细节的讨论。

我知道这很晚了,但另一个可能的原因可能是语法。也许(*() => {})可以工作,但是(9 ** () => {})呢?这是9的箭头函数的幂,返回NaN,还是9乘以生成器箭头函数,也返回NaN?它可以用一些替代语法来完成,比如=>*,正如这里的另一个答案所提到的,但可能有一个愿望,以保持生成器函数语法的一致性(例如。function* () {}{ *genMethod() {} })当它被实现时。不是什么借口,而是一个理由。

redux-saga有一个很好的解决方案

import { call, all } from 'redux-saga/effects';


function* gen() {
yield all([].map(() => {
return call(....);
}));
}

我也有同样的问题,所以来了这里。在阅读了帖子和评论后,我觉得在箭头函数中使用生成器似乎很模糊:

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 function()

但是,没有像gengenerator这样的关键字,而且箭头函数没有使用它。

结论:

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

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

这将是一个巨大的错误。让箭头函数远离生成器,这很酷。


@Bergi评论:

不。箭头函数应该是轻量级的(例如没有.prototype),通常是一行程序,而生成器则几乎相反。

我会说生成器使用的目的是run-stop-run,所以我认为我们不需要关心prototype, lexical this等。

现在你不能,但在未来你可能会,因为TC39在2019年10月发布了建议,这是第一阶段。