Iterable protokolü
Bir obje, [Symbol.iterator]() metodu varsa iterable'dır. Bu metod, her
çağrıda { value, done } dönen bir obje verir → bu da iterator'dur.
Array, String, Map, Set zaten iterable. Bu yüzden for...of ile
gezilebilirler ve [...x] ile yayılabilirler.
Manuel iterator
const range = {
start: 1,
end: 5,
[Symbol.iterator]() {
let current = this.start;
const end = this.end;
return {
next() {
return current <= end
? { value: current++, done: false }
: { value: undefined, done: true };
},
};
},
};
for (const n of range) console.log(n); // 1 2 3 4 5
[...range]; // [1, 2, 3, 4, 5]Generator fonksiyonlar
function* ile tanımlanır. yield ile değer üretir, return'e benzemez:
fonksiyonu duraklatır, bir sonraki next()'te kaldığı yerden devam eder.
function* sayilar() {
yield 1;
yield 2;
yield 3;
}
const it = sayilar();
it.next(); // { value: 1, done: false }
it.next(); // { value: 2, done: false }
it.next(); // { value: 3, done: false }
it.next(); // { value: undefined, done: true }Generatorlar otomatik olarak iterable + iterator'dır.
for (const n of sayilar()) console.log(n);
[...sayilar()]; // [1, 2, 3]Range generator
function* range(start, end, step = 1) {
for (let i = start; i <= end; i += step) yield i;
}
[...range(1, 10)]; // 1..10
[...range(0, 100, 10)]; // 0, 10, 20, ...Sonsuz dizi
Generator lazy'dir — değer ancak istendiğinde üretilir. Sonsuz dizi güvenle yazılabilir:
function* dogalSayilar() {
let n = 1;
while (true) yield n++;
}
const it = dogalSayilar();
it.next().value; // 1
it.next().value; // 2
it.next().value; // 3
// ...sonsuzfor...of ile kullanırken break ile çık.
yield* — başka iterable'a delege
function* a() {
yield 1;
yield 2;
}
function* b() {
yield 0;
yield* a(); // a()'nun değerlerini buradan ver
yield 3;
}
[...b()]; // [0, 1, 2, 3]Pratik: ağaç gezme
function* dolas(node) {
yield node.value;
for (const child of node.children ?? []) {
yield* dolas(child);
}
}
for (const v of dolas(tree)) console.log(v);Async generator
async function* ile asenkron değerler:
async function* sayfalari() {
let url = "/api/items?page=1";
while (url) {
const res = await fetch(url);
const data = await res.json();
yield data.items;
url = data.nextPage;
}
}
for await (const items of sayfalari()) {
console.log(items);
}for await...of ile gezilir. Pagination, stream işleme için ideal.
- Sonsuz dizi
- Lazy hesaplama (büyük veri)
- Stream / async chunk akışı
- Karmaşık iterable (ağaç gezme, pagination)
Yoksa basit bir dizi [] veya Array.from daha okunaklı.