--- title: function* slug: Web/JavaScript/Reference/Statements/function* tags: - ECMAScript6 - JavaScript - Итератор - Функция - Экспериментальный translation_of: Web/JavaScript/Reference/Statements/function* ---
{{jsSidebar("Statements")}}

Сводка

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 Черновик Начало работы над стандартом.
{{SpecName('ES2015', '#sec-generator-function-definitions', 'Генераторы')}} {{Spec2('ES2015')}} Изначальное определение в стандарте ECMA.

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

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

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

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

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