Какая цель звездочки (*) в функциях генератора ES6
Может кто-нибудь объяснить мне: почему функции генератора в 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
?
Ответы
Ответ 1
Три причины:
-
читаемость. Генератор сильно отличается от функции, и разница должна быть немедленно видимой (т.е. Не изучая всю реализацию в поисках выхода).
-
Общность. Естественно, что можно писать генераторы, которые не уступают и возвращаются напрямую. Кроме того, комментирование части тела (например, для отладки) не должно молча изменять, является ли что-то генератором.
-
Совместимость. Только строгий режим зарезервировал "урожай" в качестве ключевого слова, но для ES6 было сделано все, что все новые функции также доступны в неаккуратном режиме (неудачное решение IMHO, но тем не менее). Более того, даже в строгом режиме существует множество разборчивых тонкостей вокруг "урожайности"; например, рассмотрим аргументы по умолчанию:
function* g(a = yield(2)) { 'use strict' }
Без *
синтаксический анализатор мог решить только, как анализировать выход после того, как он увидел тело функции. То есть вам понадобится бесконечный внешний вид, отслеживание назад или другие хакерские приемы, чтобы справиться с этим.
Следует отметить, что (1) и (2) уже достаточно обоснованы.
(Полное раскрытие: я являюсь членом комитета EcmaScript.)
Ответ 2
Пустые генераторы (без тела) не запрещены; поэтому следует unStarredFunc()
следовать семантике генератора или нет?
По соображениям совместимости:
function yield(x) { return x };
function a() {
yield (4+1);
};
это синтаксически корректно, но вызов .next()
приведет к ошибке, тогда как добавление звездочки для явного определения генератора вызовет .next().value === 5
обнаруживает, что некоторыйгенератор содержит оператор yield во время разбора
Некоторые конструкции не могут быть разрешены во время разбора:
function someGenerator(i) {
if (glob)
return 4;
else
yield* anotherGen(i);
}
И, конечно, его проще увидеть сразу же из определения function*
, что его генератор не нуждается в том, чтобы выкапывать его источник, чтобы искать уроки.