Coba bayangin kasir bank yang panggil antrian: "Nomor 1, ke loket 3." Tunggu nomor 1 selesai dilayani, baru: "Nomor 2, ke loket 3." Kasir gak panggil semua nomor sekaligus — dia panggil satu, tunggu, panggil lagi pas siap. Itu Generator di JavaScript: fungsi yang bisa "dijeda" pas yield value, dilanjutin pas dipanggil lagi. Hemat memori (gak harus generate semua sekaligus), cocok buat lazy evaluation, infinite sequences, atau data streaming.
💡 Symbol
*wajib.function* range(...)— bintang yang nempel difunctionitu yang bilang ke JavaScript "ini generator, bukan fungsi biasa". Lupa bintang = function biasa yang error pas ketemuyield. Detail kecil yang sering kelewat.
function* hitungMundur(n) {
while (n > 0) {
yield n;
n--;
}
}
const gen = hitungMundur(3);
gen.next(); // { value: 3, done: false }
gen.next(); // { value: 2, done: false }
gen.next(); // { value: 1, done: false }
gen.next(); // { value: undefined, done: true }
Iterator Protocol:
Object yang punya method [Symbol.iterator]() bisa dipakai dengan for...of:
const angka = {
dari: 1,
sampai: 3,
[Symbol.iterator]() {
let current = this.dari;
const last = this.sampai;
return {
next() {
return current <= last
? { value: current++, done: false }
: { done: true };
}
};
}
};
for (const n of angka) console.log(n); // 1, 2, 3
Generator sebagai Iterator: Generator otomatis mengimplementasi iterator protocol:
function* range(start, end) {
for (let i = start; i <= end; i++) {
yield i;
}
}
[...range(1, 5)]; // [1, 2, 3, 4, 5]
for (const n of range(1, 3)) console.log(n);
Use case: lazy evaluation, infinite sequences, data streaming.
🎭 Analogi sehari-hari
Generator = kasir di bank yang panggil antrean satu per satu lewat speaker. "Antrean nomor 1, silakan." (gen.next()). Tidak panggil semua sekaligus — hemat tenaga, hemat memori, tunggu kasir (consumer) siap.
Iterator = aturan main "kasih satu, tunggu, kasih satu lagi". for...of paham aturan ini, otomatis ambil sampai habis.
⚠️ Jebakan yang sering ditemui
- Lupa
*difunction*= function biasa.function gen() { yield 1; }= SyntaxError. yielddi luar generator = SyntaxError.- Generator tidak bisa di-restart — sekali habis (
done: true), harus bikin instance baru.[...gen]consume habis. returndi generator =done: truedengan value. Sering di-skip pas iterate.- Spread
[...gen]materialize semua ke array — buat infinite generator = browser hang. - Async generator (
async function*) beda — yield Promise, butuhfor await. - Iterator vs Iterable beda: Iterable punya
[Symbol.iterator]()yang return Iterator. Iterator punyanext(). Generator otomatis dua-duanya. breakdifor...ofpanggilgen.return()— kalau generator punya cleanup logic difinally, jalan.
TL;DR: Generator = function yang bisa "dijeda" via yield, dilanjutin pas next() dipanggil. Sintaks function* (bintang wajib). Cocok buat lazy evaluation, infinite sequences, data streaming (hemat memory). Iterator protocol: object punya [Symbol.iterator]() yang return {next()} — bisa dipakai di for...of. Generator otomatis implement iterator. Sekali habis (done: true) gak bisa restart, harus bikin instance baru. Spread [...gen] materialize semua = JANGAN ke infinite generator.