Что такое «функция *» в 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, невозможно найти выражения со звездочками ( они используются в качестве заполнителей ).


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.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.