ES6 生成器函数中星号 (*) 的用途是什么
What's the purpose of an asterisk (*) in ES6 generator functions
谁能给我解释一下:为什么 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
存在的检测还不够?
不禁止空发电机(没有主体);那么 unStarredFunc()
是否应该遵循生成器语义?
出于兼容性原因:
function yield(x) { return x };
function a() {
yield (4+1);
};
这在语法上是正确的,但调用 .next()
会导致错误,而添加星号以显式定义生成器会导致 .next().value === 5
detect that someGenerator contains yield operator at parse time
某些构造无法在解析时解析:
function someGenerator(i) {
if (glob)
return 4;
else
yield* anotherGen(i);
}
当然,从 function*
的定义中可以更简单地立即看出它是一个生成器,而无需深入研究其源代码来寻找收益。
三个原因是:
可读性。生成器与函数有很大不同,差异应该立即可见(也就是说,无需检查整个实现来寻找收益)。
普遍性。自然应该可以写出不yield的generator,直接只写return。此外,注释掉正文的一部分(例如用于调试)不应该默默地改变某物是否是生成器。
兼容性。只有严格模式保留 'yield' 作为关键字,但 ES6 的目标是所有新功能也可以在草率模式下使用(恕我直言,这是一个不幸的决定,但尽管如此)。此外,即使在严格模式下,'yield' 也有许多解析细节;例如,考虑默认参数:
function* g(a = yield(2)) { 'use strict' }
没有*
,解析器只能在看到函数体后决定如何解析yield。也就是说,您需要无限前瞻、回溯或其他骇人听闻的技术来处理这个问题。
我应该注意到 (1) 和 (2) 已经足够了。
(完全披露:我是 EcmaScript 委员会的成员。)
谁能给我解释一下:为什么 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
存在的检测还不够?
不禁止空发电机(没有主体);那么 unStarredFunc()
是否应该遵循生成器语义?
出于兼容性原因:
function yield(x) { return x };
function a() {
yield (4+1);
};
这在语法上是正确的,但调用 .next()
会导致错误,而添加星号以显式定义生成器会导致 .next().value === 5
detect that someGenerator contains yield operator at parse time
某些构造无法在解析时解析:
function someGenerator(i) {
if (glob)
return 4;
else
yield* anotherGen(i);
}
当然,从 function*
的定义中可以更简单地立即看出它是一个生成器,而无需深入研究其源代码来寻找收益。
三个原因是:
可读性。生成器与函数有很大不同,差异应该立即可见(也就是说,无需检查整个实现来寻找收益)。
普遍性。自然应该可以写出不yield的generator,直接只写return。此外,注释掉正文的一部分(例如用于调试)不应该默默地改变某物是否是生成器。
兼容性。只有严格模式保留 'yield' 作为关键字,但 ES6 的目标是所有新功能也可以在草率模式下使用(恕我直言,这是一个不幸的决定,但尽管如此)。此外,即使在严格模式下,'yield' 也有许多解析细节;例如,考虑默认参数:
function* g(a = yield(2)) { 'use strict' }
没有
*
,解析器只能在看到函数体后决定如何解析yield。也就是说,您需要无限前瞻、回溯或其他骇人听闻的技术来处理这个问题。
我应该注意到 (1) 和 (2) 已经足够了。
(完全披露:我是 EcmaScript 委员会的成员。)