Generator에 대해서 MDN은
The Generator object is returned by a generator function and it conforms to both the iterable protocol and the iterator protocol.
이렇게 설명합니다.
iterable, iterator protocal이 무엇인지 모르니, 우선 해당 프로토콜들을 이해 해보는 시간을 가져봅시다!
혹시 아신다면, https://goto-helloworld.tistory.com/147 넘어가주세요.
The Iterable Protocol (이터러블 프로토콜)
이터러블 프로토콜은 “이 객체를 반복문에서 사용할 수 있는지”를 결정하는 규칙입니다.
- 객체가 이터러블이 되려면 [Symbol.iterator] 메서드를 구현해야 합니다.
- 이 메서드는 호출될 때 반드시 이터레이터 객체(이터레이터 프로토콜을 지키는 객체)를 반환해야 합니다.
- 예를 들어 for...of 문이 실행되면, 자바스크립트 엔진은 먼저 [Symbol.iterator]()를 호출하고, 반환된 이터레이터를 사용하여 순회할 값을 하나씩 꺼냅니다.
👉 정리하면, 이터러블 프로토콜은 “반복을 시작할 수 있는 입구를 제공하는 규칙”입니다.
이터러블 직접 구현 예시
const myIterable = {
data: [1, 2, 3],
[Symbol.iterator]() {
let index = 0;
return {
next: () => {
if (index < this.data.length) {
return { value: this.data[index++], done: false };
} else {
return { done: true };
}
}
};
}
};
for (const value of myIterable) {
console.log(value); // 1, 2, 3 출력
}
The Iterator Protocol (이터레이터 프로토콜)
이터레이터 프로토콜은 “값을 하나씩 어떻게 꺼낼 것인지”를 정의하는 규칙입니다.
- 이터레이터 객체는 반드시 next() 메서드를 가져야 합니다.
- next() 메서드는 호출될 때마다 { value, done } 형태의 객체를 반환해야 합니다.
- value: 현재 반환되는 값
- done: 더 이상 순회할 값이 없으면 true
👉 정리하면, "이터레이터 프로토콜은 “반복을 실제로 진행하면서 다음 값을 반환하는 규칙”입니다.
이터레이터 직접 구현 예시
const myIterator = {
count: 0,
next() {
if (this.count < 3) {
return { value: this.count++, done: false };
} else {
return { done: true };
}
},
[Symbol.iterator]() {
return this; // 자기 자신을 반환 → 이터러블 + 이터레이터 둘 다 만족
}
};
for (const num of myIterator) {
console.log(num); // 0, 1, 2 출력
}
이터레이터 next에 값 넣고 활용하기 예시
const myIterator = {
count: 0,
next(increment = 1) {
if (this.count < 3) {
const current = this.count;
this.count += increment; // next에 전달된 값을 활용
return { value: current, done: false };
} else {
return { done: true };
}
},
[Symbol.iterator]() {
return this; // 자기 자신을 반환 → 이터러블 + 이터레이터 둘 다 만족
}
};
// for...of는 next()에 값을 넘길 수 없기 때문에, 기본 순회에서는 increment 무시됨
for (const num of myIterator) {
console.log(num);
}
0
1
2
// 직접 next() 호출 시 값 전달 가능
const customIterator = {
count: 0,
next(step = 1) {
if (this.count < 10) {
this.count += step;
return { value: this.count, done: false };
} else {
return { done: true };
}
},
[Symbol.iterator]() {
return this;
}
};
console.log(customIterator.next(2)); // { value: 2, done: false }
console.log(customIterator.next(3)); // { value: 5, done: false }
console.log(customIterator.next(5)); // { value: 10, done: false }
내장 배열(Array) 예시
const arr = [1, 2, 3, 4, 5];
console.log(typeof arr[Symbol.iterator] === 'function'); // true → 배열은 기본적으로 이터러블
const iterator = arr[Symbol.iterator]();
console.log(typeof iterator.next === 'function'); // true → 이터레이터 프로토콜을 따름
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
위 예시에서 보시는 것처럼,
- 배열은 [Symbol.iterator]를 가지고 있어 이터러블입니다.
- [Symbol.iterator]()를 호출하면 이터레이터 객체가 반환됩니다.
- 그 이터레이터 객체에는 next() 메서드가 존재하며, 이를 통해 값을 순서대로 꺼낼 수 있습니다.
마무리
정리하자면:
- 이터러블 프로토콜: 반복 가능한 객체인지 판별하는 규칙 ([Symbol.iterator] 필요)
- 이터레이터 프로토콜: 반복을 진행하면서 값을 하나씩 꺼내는 규칙 (next() 필요)
제너레이터의 구체적인 동작 방식과 활용법은 다음 시간에 이어서 설명드리겠습니다.
참고자료
'FE > JS' 카테고리의 다른 글
| Generator 이해하기 (2) - 마무리 (0) | 2025.09.26 |
|---|---|
| 자바스크립트 - 클로저 (0) | 2025.05.19 |
| JavaScript - this (0) | 2025.05.19 |
| 자바스크립트 실행 컨텍스트 (0) | 2025.05.19 |
| 자바스크립트 호이스팅 정리 (0) | 2025.05.18 |