A .map() és a .filter() évek óta ott van a tömbjeidben, de 2025 óta már nem csak a tömböké. Az Iterator objektumnak saját prototípus-metódusai lettek: map, filter, take, drop, reduce, toArray és még pár. Ugyanazok a nevek, de más a viselkedésük – és ez a különbség pont ott számít, ahol a klasszikus tömbmetódusok fájnak: nagy adathalmazoknál és végtelen sorozatoknál.

Mi pontosan az Iterator helpers
A TC39 Iterator Helpers javaslat Stage 4-re jutott, és a finished-proposals lista szerint 2025-ben zárult le a specifikációba. A lényege egyszerű: az Iterator.prototype-ra felkerültek azok a metódusok, amiket eddig csak a Array.prototype-on ismertünk – map, filter, take, drop, flatMap, reduce, toArray, forEach, some, every, find –, plusz egy Iterator.from() statikus metódus, amivel bármilyen, csak next()-et implementáló objektumot fel lehet öltöztetni ezekkel a képességekkel.
Böngészőtámogatás MDN szerint: Chrome/Edge 122 (2024. február), Firefox 131 (2024. október), Safari 18.4 (2025. március), Node.js pedig 22.0.0 óta. 2026-ban ez már minden nagy motoron elérhető, tehát nem egy Chrome-only kuriózumról van szó. A Node.js oldalán a nodejs/node#51362 PR vezette be az új globális Iterator kezelését a v22-es fősorban.
A lényeg: lusta kiértékelés
A [1,2,3].map(f) azonnal lefut, és egy teljes új tömböt ad vissza. Az Iterator helperek ehelyett egy másik iterátort adnak vissza – a tényleges munka csak akkor történik meg, amikor valaki elkéri a következő elemet. Ez lehetővé teszi, hogy végtelen sorozatokon dolgozzunk anélkül, hogy a program felakadna:
function* naturalNumbers() {
let n = 1;
while (true) yield n++;
}
const firstThreeEvenSquares = naturalNumbers()
.map(n => n * n)
.filter(n => n % 2 === 0)
.take(3)
.toArray();
console.log(firstThreeEvenSquares); // [ 4, 16, 36 ]
A naturalNumbers() egy sosem leálló generátor. Ha ezt egy sima Array.from()-mal vagy [...naturalNumbers()]-lel próbálnád tömbbé alakítani, a program lefagyna – nem lenne hol megállnia. A .take(3) viszont pontosan azt garantálja, hogy a lánc csak addig kér elemet a generátortól, amíg három találat össze nem gyűlik, aztán leáll. Ez a fajta korlátozott, igény szerinti feldolgozás korábban csak kézzel írt ciklussal volt egyszerűen megoldható.
A gyakori félreértés: arr.map() nem ez
Ez a legfontosabb csapda. A Array.prototype.map nem lett kicserélve – [1,2,3].map(f) továbbra is a régi, azonnal kiértékelő metódus, és tömböt ad vissza, nem iterátort. Az új, lusta viselkedést csak akkor kapod meg, ha explicit iterátort kérsz a tömbtől, például a .values()-szel:
const numbers = [1, 2, 3, 4, 5, 6, 7, 8];
// Klasszikus: minden lépés teljes új tömböt hoz létre
const classic = numbers.filter(n => n % 2 === 0).map(n => n * 10);
// Iterator helper: egyetlen menetben, köztes tömb nélkül
const lazy = numbers.values().filter(n => n % 2 === 0).map(n => n * 10).toArray();
console.log(classic); // [ 20, 40, 60, 80 ]
console.log(lazy); // [ 20, 40, 60, 80 ] – ugyanaz az eredmény
console.log(Array.isArray(numbers.map(n => n))); // true – a régi metódus
console.log(numbers.values().map(n => n).constructor.name); // 'Iterator' – az új
A kettő ugyanazt az eredményt adja, de a klasszikus verzió a filter-nél lefoglal egy teljes köztes tömböt, amit aztán a map egy másik tömbre alakít át. Nyolc elemnél ez nem számít, de egy több tízezer soros feldolgozási láncban ez felesleges memóriaforgalom és garbage collector-terhelés – főleg, ha a lánc négy-öt lépésből áll.
Nem csak generátoron: bármin, ami iterálható
Az Iterator helperek ott jelennek meg, ahol iterátorral dolgozol – ez a Map és a Set beépített iterátoraira is igaz:
const cache = new Map([['a', 1], ['b', 2], ['c', 3]]);
console.log(cache.entries().filter(([, v]) => v > 1).toArray());
// [ [ 'b', 2 ], [ 'c', 3 ] ]
Ha viszont saját, kézzel írt iterátorod van – egy objektum, ami csak a next()-et implementálja, de nem örököl az Iterator.prototype-tól –, az Iterator.from() öltözteti fel a helperekkel:
function createRange(start, end) {
let current = start;
return {
next() {
if (current > end) return { done: true, value: undefined };
return { done: false, value: current++ };
},
};
}
const range = Iterator.from(createRange(1, 10));
console.log(range.filter(n => n % 3 === 0).toArray()); // [ 3, 6, 9 ]
Ez különösen hasznos, ha egy régebbi API vagy saját osztály csak a minimális iterátorprotokollt implementálja – nem kell átírni, elég egyszer becsomagolni.
Ahol elakadhatsz
- A
reduce()kezdőérték nélkül ugyanúgy hibát dob, mint aArray.prototype.reduce:TypeError: Reduce of a done iterator with no initial value, ha az iterátor üres. - Egy iterátor csak egyszer fogyasztható el. Ha a lánc végén kétszer hívod a
.toArray()-t (vagy előbb.some()-mal, utána.toArray()-vel járod körbe), a második hívás már kiürült iterátort kap. - Régebbi böngészőt vagy Node-ot (a 2024 előtti verziókat) még ki kell zárni, vagy a core-js
core-js/proposals/iterator-helperspolyfillját kell bevonni – natív implementáció nélkül a.values().map()simánTypeError-ral bukik el.
A gyakorlatban ott érdemes bevetni, ahol tényleg sok elemen és több egymásra épülő lépésen kell végigmenni – log-sorok szűrése és transzformálása, egy nagy Map-ből kiválasztott rekordok feldolgozása, vagy bármi, ahol eddig kézzel írt for...of ciklusba kényszerültél, mert a klasszikus tömbmetódusok korai megállítása (a mai .take() hiányában) nem volt kényelmesen kifejezhető. Kis, egyszeri átalakításnál a klasszikus .filter().map() továbbra is teljesen rendben van – a lustaság ára egy plusz mentális modell, amit nem minden háromelemű tömbnél kell bevállalni.