From 218934fa2ed1c702a6d3923d2aa2cc6b43c48684 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:43:23 -0500 Subject: initial commit --- .../reference/statements/function_star_/index.html | 268 +++++++++++++++++++++ 1 file changed, 268 insertions(+) create mode 100644 files/uk/web/javascript/reference/statements/function_star_/index.html (limited to 'files/uk/web/javascript/reference/statements/function_star_/index.html') diff --git a/files/uk/web/javascript/reference/statements/function_star_/index.html b/files/uk/web/javascript/reference/statements/function_star_/index.html new file mode 100644 index 0000000000..f900241ddc --- /dev/null +++ b/files/uk/web/javascript/reference/statements/function_star_/index.html @@ -0,0 +1,268 @@ +--- +title: function* +slug: Web/JavaScript/Reference/Statements/function* +tags: + - ECMAScript 2015 + - Function + - JavaScript + - Ітератор + - генератор +translation_of: Web/JavaScript/Reference/Statements/function* +--- +
{{jsSidebar("Statements")}}
+ +

Оголошення function* (ключове слово function з зірочкою) визначає функцію-генератор, яка повертає об'єкт {{jsxref("Global_Objects/Generator","Generator")}}.

+ +
{{EmbedInteractiveExample("pages/js/statement-functionasterisk.html")}}
+ + + +

Ви також можете визначати функції-генератори за допомогою конструктора {{jsxref("GeneratorFunction")}} або функціонального виразу.

+ +

Синтаксис

+ +
function* name([param[, param[, ... param]]]) {
+   statements
+}
+
+ +
+
name
+
Ім'я функції.
+
+ +
+
param
+
Ім'я формального параметра функції.
+
+ +
+
statements
+
Інструкції, що складають тіло функції.
+
+ +

Опис

+ +

Генератори - це функції, з яких можна вийти та пізніше повторно зайти. Їхній контекст (зв'язування змінних) збережеться між заходами.
+
+ Генератори у JavaScript -- особливо у поєднанні з промісами -- дуже потужний інструмент асинхронного програмування, бо вони пом'якшують -- якщо не усувають повністю -- проблеми зворотних викликів, такі як Пекло зворотних викликів та Інверсія управління.

+ +

Виклик функції-генератора не виконує тіло функції негайно; замість цього повертається об'єкт-ітератор для функції. Коли викликається метод ітератора next(), тіло функції-генератора виконується до першого виразу {{jsxref("Operators/yield", "yield")}}, який визначає значення, що має бути повернене ітератором, або, оператором {{jsxref("Operators/yield*", "yield*")}}, делегується до іншої функції-генератора. Метод next() повертає об'єкт з властивістю value, що містить отримане значення, та властивістю done, яка вказує, чи генератор віддав останнє значення, у вигляді булевого значення. Виклик метода next() з аргументом відновить виконання функції-генератора, замінюючи вираз yield в тій точці, де виконання було призупинене, аргументом з next().

+ +

Оператор return у генераторі змусить генератор завершити виконання (тобто, властивості done поверненого об'єкта буде присвоєне значення true). Якщо повертається значення, воно буде присвоєте властивості value об'єкта, що повертається генератором.
+ Схоже на оператор return, викидання помилки всередині генератора змусить генератор завершити виконання -- якщо не буде перехоплене у тілі генератора.
+ Коли генератор завершує виконання, наступні виклики next не виконають жодного коду генератора, вони лише повернуть об'єкт наступного вигляду: {value: undefined, done: true}.

+ +

Приклади

+ +

Простий приклад

+ +
function* idMaker() {
+  var index = 0;
+  while (true)
+    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); // 3
+// ...
+ +

Приклад з 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
+
+ +

Передача аргументів у об'єкти Generator

+ +
function* logGenerator() {
+  console.log(0);
+  console.log(1, yield);
+  console.log(2, yield);
+  console.log(3, yield);
+}
+
+var gen = logGenerator();
+
+// перший виклик метода next виконує функцію з початку
+// до першого оператора yield
+gen.next();             // 0
+gen.next('крендель');   // 1 крендель
+gen.next('кава');       // 2 кава
+gen.next('майонез');    // 3 майонез
+
+ +

Оператор return у генераторі

+ +
function* yieldAndReturn() {
+  yield "Y";
+  return "R";
+  yield "недосяжний";
+}
+
+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 }
+
+ +

Генератор як властивість об'єкта

+ +
const someObj = {
+  *generator () {
+    yield 'а';
+    yield 'б';
+  }
+}
+
+const gen = someObj.generator()
+
+console.log(gen.next()); // { value: 'а', done: false }
+console.log(gen.next()); // { value: 'б', done: false }
+console.log(gen.next()); // { value: undefined, done: true }
+
+ +

Генератор як метод класу

+ +
class Foo {
+  *generator () {
+    yield 1;
+    yield 2;
+    yield 3;
+  }
+}
+
+const f = new Foo ();
+const gen = f.generator();
+
+console.log(gen.next()); // { value: 1, done: false }
+console.log(gen.next()); // { value: 2, done: false }
+console.log(gen.next()); // { value: 3, done: false }
+console.log(gen.next()); // { value: undefined, done: true }
+
+ +

Генератор як обчислювана властивість

+ +
class Foo {
+  *[Symbol.iterator] () {
+    yield 1;
+    yield 2;
+  }
+}
+
+const SomeObj = {
+  *[Symbol.iterator] () {
+    yield 'а';
+    yield 'б';
+  }
+}
+
+console.log(Array.from(new Foo)); // [ 1, 2 ]
+console.log(Array.from(SomeObj)); // [ 'а', 'б' ]
+
+ +

Генератори не є конструкторами

+ +
function* f() {}
+var obj = new f; // викидає "TypeError: f is not a constructor
+
+ +

Генератор, визначений у виразі

+ +
const foo = function* () {
+  yield 10;
+  yield 20;
+};
+
+const bar = foo();
+console.log(bar.next()); // {value: 10, done: false}
+ +

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

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
СпецифікаціяСтатусКоментар
{{SpecName('ES2015', '#sec-generator-function-definitions', 'function*')}}{{Spec2('ES2015')}}Початкове визначення.
{{SpecName('ES2016', '#sec-generator-function-definitions', 'function*')}}{{Spec2('ES2016')}}Внесено зміни, що генератори не повинні мати пастки [[Construct]] та викидатимуть помилку при використанні з new.
{{SpecName('ESDraft', '#sec-generator-function-definitions', 'function*')}}{{Spec2('ESDraft')}}
+ +

Сумісність з веб-переглядачами

+ +
+ + +

{{Compat("javascript.statements.generator_function")}}

+
+ +

Примітки щодо Firefox

+ +

Генератори та ітератори у Firefox до 26-ї версії

+ +

Старші версії Firefox реалізують старшу версію пропозиції генераторів. У старшій версії генератори визначались за допомогою звичайного ключового слова function (без зірочки), серед інших відмінностей. Дивіться більше інформації у статті Застаріла функція-генератор.

+ +

Замість викидання помилки повертається об'єкт IteratorResult

+ +

Починаючи з Gecko 29 {{geckoRelease(29)}}, завершена функція-генератор більше не викидає помилку {{jsxref("TypeError")}} "generator has already finished". Замість цього, вона повертає об'єкт IteratorResult у вигляді { value: undefined, done: true } ({{bug(958951)}}).

+ +

Див. також

+ + -- cgit v1.2.3-54-g00ecf