Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Генератори та ітератори». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Ітератор** - це об'єкт із методом `next()`, що повертає `{ value, done }`, а **генератор** (`function*`) - це зручний спосіб створити такий ітератор, не реалізуючи `next()` вручну. **Ключове:** генератори - це синтаксичний цукор над створенням ітераторів, і об'єкт-генератор одразу реалізує і ітераторний, і ітерований протокол (`Symbol.iterator`), тому його можна використовувати у `for...of`.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## 1. Що таке ітератори (коротко) **Ітератор** - це об'єкт, який дозволяє **поелементно перебирати значення**. Він повинен реалізовувати **метод** `next()`, який повертає об'єкт формату: ```javascript { value: <значення>, done: <булеве> } ``` Приклад простого ручного ітератора: ```javascript const iterator = { current: 0, next() { if (this.current < 3) { return { value: this.current++, done: false }; } else { return { value: undefined, done: true }; } } }; console.log(iterator.next()); // { value: 0, done: false } console.log(iterator.next()); // { value: 1, done: false } console.log(iterator.next()); // { value: 2, done: false } console.log(iterator.next()); // { value: undefined, done: true } ``` **Ітератор** - це об'єкт, який знає, *як видавати значення по одному*. --- ## 2. Що таке генератор **Генератор** (`function*`) - це **зручний спосіб створити ітератор**, не реалізуючи `next()` вручну. Коли ти викликаєш `function*`, вона **повертає об'єкт-генератор**, який **вже реалізує ітераторний протокол**. --- ## 3. Генератор *є* ітератором ```javascript function* gen() { yield 10; yield 20; yield 30; } const iterator = gen(); console.log(iterator.next()); // { value: 10, done: false } console.log(iterator.next()); // { value: 20, done: false } console.log(iterator.next()); // { value: 30, done: false } console.log(iterator.next()); // { value: undefined, done: true } ``` - `iterator` - це об'єкт-генератор; - у нього є метод `next()`, що повертає `{ value, done }`; - отже, **він повністю відповідає протоколу ітератора**. --- ## 4. Генератор також є *ітерованим об'єктом* Генератор реалізує не лише **ітераторний**, а й **ітерований протокол**, тому що в нього є метод `Symbol.iterator`: ```javascript function* gen() { yield 1; yield 2; yield 3; } const it = gen(); console.log(typeof it[Symbol.iterator]); // "function" console.log(it[Symbol.iterator]() === it); // true ``` Це означає, що генератор: - можна використовувати в `for...of`; - можна розпилювати (`...`); - можна передавати в `Array.from()`, `Promise.all()` тощо. --- ## 5. Приклад використання генератора як ітератора ```javascript function* numbers() { yield 1; yield 2; yield 3; } for (const n of numbers()) { console.log(n); } ``` Виведе: ```javascript 1 2 3 ``` `for...of` автоматично викликає `next()` у генератора, поки `done: false`. --- ## 6. Зв'язок між ітераторами і генераторами | Властивість | Ітератор | Генератор | |---|---|---| | Що це | Об'єкт з методом `next()` | Функція, що повертає ітератор | | Повертає | `{ value, done }` | `{ value, done }` | | Створюється вручну | так | ні, автоматично | | Керує станом вручну | так | ні, автоматично всередині `function*` | | Можна використовувати в `for...of` | Тільки якщо реалізує `[Symbol.iterator]` | так (реалізовано типово) | Тобто: **генератори - це синтаксичний цукор над створенням ітераторів.** --- ## 7. "Ручний ітератор" vs "генератор" ### Без генератора: ```javascript function makeIterator(array) { let i = 0; return { next() { return i < array.length ? { value: array[i++], done: false } : { value: undefined, done: true }; } }; } const it = makeIterator(['a', 'b', 'c']); console.log(it.next()); // { value: 'a', done: false } ``` ### З генератором: ```javascript function* makeIterator(array) { for (const item of array) yield item; } const it = makeIterator(['a', 'b', 'c']); console.log(it.next()); // { value: 'a', done: false } ``` Генератори **прибирають усю ручну логіку стану**, зберігаючи при цьому ту саму поведінку. --- ## 8. Генератори дозволяють створювати "нескінченні ітератори" ```javascript function* infiniteCounter() { let i = 1; while (true) yield i++; } const it = infiniteCounter(); console.log(it.next().value); // 1 console.log(it.next().value); // 2 console.log(it.next().value); // 3 ``` Це неможливо зі звичайним масивом, але ітератори (і генератори) підтримують "ліниву" нескінченність. --- ## ПІДСУМОК | Концепція | Ітератор | Генератор | |---|---|---| | Що це | Об'єкт з методом `next()` | Функція, що повертає ітератор | | Керування станом | Ручне | Автоматичне | | Протокол | Ітераторний | Ітераторний + Ітерований | | Метод `Symbol.iterator` | Зазвичай потрібно додати вручну | Є типово | | Можна використовувати в `for...of` | Тільки якщо реалізований `[Symbol.iterator]` | завжди | | Обчислення | Ліниві | Ліниві | | Зручність | Низька | Висока | --- **Підсумок в одній фразі:** > Генератор - це зручний спосіб **створити ітератор**, > не реалізуючи вручну `next()`, `done` і внутрішній стан.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.