Contents
see ListES2025에서 정식 도입된 Iterator Helpers는 자바스크립트의 이터레이터 활용 방식을 근본적으로 바꿔놓았습니다. 기존에는 배열로 변환해야만 사용할 수 있었던 map, filter, reduce 등의 메서드를 이터레이터에서 직접 체이닝할 수 있게 되었습니다. 지연 평가(lazy evaluation) 덕분에 메모리 효율도 크게 향상됩니다.
기존 방식의 한계
이전에는 이터레이터를 활용하려면 반드시 배열로 변환해야 했습니다.
// 기존 방식: 전체를 배열로 변환 후 처리
function* generateNumbers() {
for (let i = 0; i < 1000000; i++) yield i;
}
// 100만 개 전부 배열로 만든 후 필터링 - 메모리 낭비
const result = [...generateNumbers()]
.filter(n => n % 2 === 0)
.map(n => n * 3)
.slice(0, 10);
// 10개만 필요한데 100만 개를 모두 메모리에 올림
Iterator Helpers 기본 사용법
ES2025 Iterator Helpers를 사용하면 지연 평가로 필요한 만큼만 처리합니다.
function* generateNumbers() {
for (let i = 0; i < 1000000; i++) yield i;
}
// Iterator Helpers: 지연 평가로 필요한 만큼만 처리
const result = generateNumbers()
.filter(n => n % 2 === 0)
.map(n => n * 3)
.take(10)
.toArray();
console.log(result);
// [0, 6, 12, 18, 24, 30, 36, 42, 48, 54]
// 실제로 20개만 순회하고 중단됨
주요 메서드 상세
.map(fn)
각 요소를 변환하는 새 이터레이터를 반환합니다.
const names = ['alice', 'bob', 'charlie'];
const upper = names.values()
.map(name => name.toUpperCase())
.toArray();
// ['ALICE', 'BOB', 'CHARLIE']
.filter(fn)
조건을 만족하는 요소만 통과시키는 이터레이터를 반환합니다.
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const evens = numbers.values()
.filter(n => n % 2 === 0)
.toArray();
// [2, 4, 6, 8, 10]
.take(n)
처음 n개 요소만 가져오는 이터레이터를 반환합니다.
function* fibonacci() {
let a = 0, b = 1;
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
const first10 = fibonacci().take(10).toArray();
// [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
.drop(n)
처음 n개 요소를 건너뛰는 이터레이터를 반환합니다.
const afterFirst5 = fibonacci().drop(5).take(5).toArray();
// [5, 8, 13, 21, 34]
.flatMap(fn)
각 요소를 이터레이터로 변환하고 평탄화합니다.
const sentences = ['hello world', 'foo bar baz'];
const words = sentences.values()
.flatMap(s => s.split(' '))
.toArray();
// ['hello', 'world', 'foo', 'bar', 'baz']
.reduce(fn, initial)
이터레이터의 모든 요소를 하나의 값으로 축약합니다. 이 메서드만 즉시 실행됩니다.
const sum = [1, 2, 3, 4, 5].values()
.reduce((acc, n) => acc + n, 0);
// 15
.forEach(fn)
각 요소에 대해 부수 효과를 실행합니다.
[1, 2, 3].values()
.map(n => n * 10)
.forEach(n => console.log(n));
// 10
// 20
// 30
.some(fn) / .every(fn)
조건을 만족하는 요소가 있는지(some) 또는 전부 만족하는지(every) 확인합니다.
const hasNegative = [-1, 2, 3].values().some(n => n < 0);
// true
const allPositive = [1, 2, 3].values().every(n => n > 0);
// true
.find(fn)
조건을 만족하는 첫 번째 요소를 반환합니다.
const firstEven = [1, 3, 4, 7, 8].values().find(n => n % 2 === 0);
// 4
Iterator.from()으로 일반 이터러블 감싸기
배열이 아닌 이터러블 객체에도 헬퍼를 적용할 수 있습니다.
// Map 객체에 Iterator Helpers 적용
const userMap = new Map([
['u1', { name: 'Alice', age: 30 }],
['u2', { name: 'Bob', age: 17 }],
['u3', { name: 'Charlie', age: 25 }]
]);
const adultNames = Iterator.from(userMap.values())
.filter(user => user.age >= 18)
.map(user => user.name)
.toArray();
// ['Alice', 'Charlie']
// Set 객체에 적용
const uniqueEvenSquares = Iterator.from(new Set([1, 2, 3, 4, 5]))
.filter(n => n % 2 === 0)
.map(n => n ** 2)
.toArray();
// [4, 16]
실전 활용: 대용량 로그 파일 스트림 처리
import { createReadStream } from 'fs';
import { createInterface } from 'readline';
async function analyzeErrorLogs(filePath) {
const rl = createInterface({
input: createReadStream(filePath)
});
// readline의 비동기 이터레이터를 활용
const errors = [];
for await (const line of rl) {
if (line.includes('ERROR')) {
errors.push(line);
if (errors.length >= 100) break; // 최근 100개만
}
}
return errors;
}
// 동기 이터레이터에서는 Iterator Helpers가 더 깔끔
function processData(dataArray) {
return dataArray.values()
.filter(item => item.status === 'error')
.map(item => ({
timestamp: item.ts,
message: item.msg,
severity: item.level
}))
.take(50)
.toArray();
}
성능 비교
100만 개의 숫자에서 짝수만 골라 제곱하고 처음 10개를 가져오는 작업의 성능을 비교하면, 배열 방식은 전체를 메모리에 올려 처리 시간과 메모리 사용량이 크지만, Iterator Helpers는 20개 요소만 순회하므로 처리 시간은 수백 배 빠르고 메모리 사용량은 거의 0에 가깝습니다. 대용량 데이터를 다루거나 무한 시퀀스를 처리할 때 Iterator Helpers는 필수적인 도구입니다.
브라우저 및 런타임 지원
2026년 4월 기준 Chrome 122+, Firefox 131+, Safari 18.2+, Node.js 22+, Deno 1.42+에서 지원됩니다. 구형 환경에서는 core-js 폴리필로 대체할 수 있습니다.
npm install core-js
// 진입점에서 폴리필 로드
import 'core-js/proposals/iterator-helpers';