Подтвердить что ты не робот

Какая цель звездочки (*) в функциях генератора 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?

4b9b3361

Ответ 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*, что его генератор не нуждается в том, чтобы выкапывать его источник, чтобы искать уроки.