**이터레이터(iterator)**는 { value, done }을 반환하는 next() 메서드를 가진 객체입니다. 객체가 [Symbol.iterator] 메서드를 가지면 **이터러블(iterable)**이며 — 이것이 for...of와 스프레드가 동작하게 만드는 것입니다. 제너레이터(generator)(function*)는 yield로 이터레이터를 만드는 편리한 방법입니다.
**이터레이터(iterator)**는 { value, done }을 반환하는 next() 메서드를 가진 객체입니다. 객체가 [Symbol.iterator] 메서드를 가지면 **이터러블(iterable)**이며 — 이것이 for...of와 스프레드가 동작하게 만드는 것입니다. 제너레이터(generator)(function*)는 yield로 이터레이터를 만드는 편리한 방법입니다.
function* idGenerator() {
let id = 1;
while (true) { // 무한이지만 지연됨 — 요청 시에만 계산
yield id++; // 여기서 멈추고 값을 반환, next()에서 재개
}
}
const gen = idGenerator();
gen.next().value; // 1
gen.next().value; // 2 — 멈췄던 곳에서 실행이 재개됨
핵심 아이디어: 실행이 각 yield에서 **중단(suspend)**되고 다음 .next()에서 재개되며, 호출 간에 지역 상태를 보존합니다. 요청하기 전까지는 아무것도 계산되지 않습니다.
// 모든 것을 메모리에 만들지 않고 거대한/무한한 시퀀스를 처리
function* take(iterable, n) {
let i = 0;
for (const x of iterable) {
if (i++ >= n) return;
yield x;
}
}
[...take(idGenerator(), 3)]; // [1, 2, 3] — 무한 제너레이터로부터
const range = {
from: 1, to: 3,
*[Symbol.iterator]() { for (let i = this.from; i <= this.to; i++) yield i; },
};
[...range]; // [1, 2, 3] — for...of 및 스프레드와 함께 동작
제너레이터는 지연/무한 시퀀스, 커스텀 반복, 메모리 효율적인 스트리밍을 가능하게 합니다.
또한 초기 비동기 라이브러리(co)의 기반이었고, 비동기 반복(for await...of)의 토대입니다.
이터레이터 프로토콜은 배열, Map, Set, 문자열 전반에 걸쳐 for...of, 스프레드, 구조 분해를 통합하는 것입니다.