Что такое «функция *» в JavaScript?

243

На этой странице я нашел новый тип функции JavaScript:

// NOTE: "function*" is not supported yet in Firefox.
// Remove the asterisk in order for this code to work in Firefox 13 

function* fibonacci() { // !!! this is the interesting line !!!
    let [prev, curr] = [0, 1];
    for (;;) {
        [prev, curr] = [curr, prev + curr];
        yield curr;
    }
}

Я уже знаю , что yield, letи [?,?]=[?,?]делать , но не имею ни малейшего представления о том , что function*это должно быть. Что это?

PS не пытайтесь попробовать Google, невозможно найти выражения со звездочками ( они используются в качестве заполнителей ).

Строка QNA
источник
4
Комментарий в примере довольно старый, function*синтаксис поддерживается в Firefox начиная с версии 26: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… *. Старые версии использовали другой синтаксис.
Николай
39
Что касается Google, просто выполните поиск «звездочка функции» или «звездочка функции». Вот так я и нашел этот вопрос;).
trysis
2
Похоже, что *был удален из ссылки от @Nickolay. Вот ссылка непосредственно function*на MDN . Конечно же, «базовая» поддержка начиная с v26 .
Рябин
Еще одна ссылка MDN (которую, кстати, я нашел на странице MDN, на которую
ссылается
Еще одна полезная ссылка на MDN: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… *
Логан,

Ответы:

199

Это функция генератора .

Генераторы - это функции, которые можно завершить, а затем снова ввести. Их контекст (привязки переменных) будет сохранен при повторном входе.

Вызов функции генератора не выполняет ее тело немедленно; вместо этого возвращается объект-итератор для функции. Когда next()вызывается метод итератора, тело функции генератора выполняется до первого yieldвыражения, которое указывает значение, которое будет возвращено из итератора или, с помощью yield*, делегатов другой функции генератора.


Историческая справка:

Это предложенный синтаксис для EcmaScript.next.

Дейв Герман из Mozilla выступил с докладом о EcmaScript.next . В 30:15 он говорит о генераторах.

Ранее он объяснял, как Mozilla экспериментально внедряет предложенные изменения языка для управления комитетом. Дейв тесно сотрудничает с Бренданом Эйчем, техническим директором Mozilla (я думаю) и оригинальным дизайнером JavaScript.

Вы можете найти более подробную информацию в вики рабочей группы EcmaScript: http://wiki.ecmascript.org/doku.php?id=harmony:generators

Рабочая группа (TC-39) имеет общее согласие с тем, что EcmaScript.next должен иметь какое-то предложение генератора итератора, но это не является окончательным.

Вы не должны полагаться на это отображение без изменений в следующей версии языка, и даже если оно не изменится, оно, вероятно, не будет отображаться в других браузерах некоторое время.

обзор

Сопрограммы первого класса, представленные в виде объектов, инкапсулирующих приостановленные контексты выполнения (т. Е. Активации функций). Предшествующий уровень техники: Python, Icon, Lua, Scheme, Smalltalk.

Примеры

«Бесконечная» последовательность чисел Фибоначчи (несмотря на поведение около 2 53 ):

function* fibonacci() {
    let [prev, curr] = [0, 1];
    for (;;) {
        [prev, curr] = [curr, prev + curr];
        yield curr;
    }
}

Генераторы могут быть повторены в циклах:

for (n of fibonacci()) {
    // truncate the sequence at 1000
    if (n > 1000)
        break;
    print(n);
}

Генераторы являются итераторами:

let seq = fibonacci();
print(seq.next()); // 1
print(seq.next()); // 2
print(seq.next()); // 3
print(seq.next()); // 5
print(seq.next()); // 8
Майк Самуэль
источник
7
Продолжение: что делает цикл for без параметров ( for(;;))? Зачем использовать это в этом контексте?
Ферги
13
@Fergie, так for(;;)же, как while (true). Он используется в этом контексте, поскольку последовательность Фибоначчи является неограниченной последовательностью.
Майк Самуэль
5
Предшествующий уровень техники: C # выход?
Дейв Ван ден Эйнде
3
@DaveVandenEynde, предшествующий уровень техники: выход Python. Предшествующий уровень техники: CLU и Icon.
Майк Самуэль
52

Это функция генератора - и так сказано на странице, которую вы цитируете, в комментарии, которую вы заменили на «это интересная строка» ...

По сути, это способ задавать последовательности программным образом, чтобы их можно было передавать и доступ к элементам по индексу без необходимости предварительно вычислять всю последовательность (возможно, бесконечной по размеру).

Майкл Боргвардт
источник
10
«Доступ по индексу без необходимости вычисления всей последовательности», возможно, является наиболее полезным объяснением генераторов, с которыми я когда-либо сталкивался. Я мог видеть использование этого в приложении против ранее только теоретического понимания этого.
Уэс
11

В function*выглядит типа как он действует в качестве функции генератора для процессов , которые могут быть итерировать. C # имеет такую ​​функцию, используя «return return», см. 1 и см. 2

По сути, это возвращает каждое значение одно за другим к любой итерации этой функции, поэтому их сценарий использования показывает это в цикле стиля foreach.

invalidsyntax
источник