MDN will be in maintenance mode on Thursday September 21st, starting at 10 AM Pacific / 5 PM UTC, for about 1 hour.

Это экспериментальная технология, часть предложения Harmony (ECMAScript 6).
Поскольку спецификация этой технологии ещё не стабилизировалась, проверьте таблицу совместимости её использования в различных браузерах. Также обратите внимание, что синтаксис и поведение экспериментальной технологии могут быть изменены в будущих версиях браузеров в соответствии с изменениями в спецификации.

Сводка

function* (ключевое слово function со звёздочкой) определяет функцию-генератор.

Синтаксис

function* name([param[, param[, ... param]]]) { statements }
name
Имя функции.
param
Именованные аргументы функции (параметры). Функция-генератор может иметь 255 аргументов.
statements
Инструкции составляющие тело функции.

Описание

Генераторы являются функциями с возможностью выхода и последующего входа. Их контекст исполнения (значения переменных) сохраняется при последующих входах.

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

Примеры

Простой пример

function* idMaker() {
  var index = 0;
  while (index < 3)
    yield index++;
}

var gen = idMaker();

console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // undefined
// ...

Пример с yield*

function* anotherGenerator(i) {
  yield i + 1;
  yield i + 2;
  yield i + 3;
}

function* generator(i) {
  yield i;
  yield* anotherGenerator(i);
  yield i + 10;
}

var gen = generator(10);

console.log(gen.next().value); // 10
console.log(gen.next().value); // 11
console.log(gen.next().value); // 12
console.log(gen.next().value); // 13
console.log(gen.next().value); // 20

Передача аргументов в генератор

function* logGenerator() {
  console.log(yield);
  console.log(yield);
  console.log(yield);
}

var gen = logGenerator();

// первый вызов next выполняется от начала функции
// и до первого оператора yield
gen.next(); 
gen.next('pretzel'); // pretzel
gen.next('california'); // california
gen.next('mayonnaise'); // mayonnaise

Инструкция return в генераторе

function* yieldAndReturn() {
  yield "Y";
  return "R";
  yield "unreachable";
}

var gen = yieldAndReturn()
console.log(gen.next()); // { value: "Y", done: false }
console.log(gen.next()); // { value: "R", done: true }
console.log(gen.next()); // { value: undefined, done: true }

Генераторы не могут быть инстанцированы (not constructable)

function* f() {}
var obj = new f; // throws "TypeError: f is not a constructor"

Спецификации

Спецификация Статус Комментарий
Предложение Harmony Черновик Начало работы над стандартом.
ECMAScript 2015 (6th Edition, ECMA-262)
Определение 'Генераторы' в этой спецификации.
Стандарт Изначальное определение в стандарте ECMA.

Совместимость с браузерами

Возможность Chrome Firefox (Gecko) Internet Explorer Opera Safari (WebKit)
Базовая поддержка 39 26.0 (26.0) Нет 26 Нет
Возможность Android Firefox Mobile (Gecko) IE Phone Opera Mobile Safari Mobile
Базовая поддержка yes (when?) 27.0 (27.0) Нет Нет Нет

Генераторы и итераторы до версии Firefox 26

В старых версиях Firefox была реализована иная версия генераторов. В ней генераторы определялись обычным ключевым словом function (без звёздочки) и имели некоторые другие отличия.

Смотрите также

Метки документа и участники

 Внесли вклад в эту страницу: MaksymI, kdex, deman, MalkavianMax, BychekRU, dtretyakov
 Обновлялась последний раз: MaksymI,