제너레이터
- Iterator이자 Iterable을 생성하는 함수
- Iterator를 return하는 함수
function* gen() {
yield 1;
yield 2;
yield 3;
}
let iter = gent();
console.log(iter[Symbol.iterator]); // [Symbol.iterator]()를 가지고 있음
console.log(iter[Symbol.iterator]() === iter); // true
console.log(iter.next()); // {value:1, done:false}
- 또한 Well-Formed-Iterator임(Iterator를 리턴하는데 그 것이 자기 자신과 동일)
- 그래서 순회 가능
for (const a of gen()) console.log(a); // 1,2,3
- 순회를 할 때 문장으로 표현 가능
function* gen() {
yield 1;
if (false) yield 2;
yield 3;
}
let iter = gent();
for (const a of gen()) console.log(a); // 1,3
—> 이렇게되면 JS에서 제너레이터 내부 문장을 통해 순회할 수 있도록 만들 수 있음
—> 즉, 다양한 값들을 제너레이터를 통해서 순회할 수 있도록 할 수 있음
주의 사항
- 제너레이터에 return값을 명시할 수 있지만
- 순회할 때에는 나오지 않음
function* gen() {
yield 1;
yield 2;
yield 3;
return 100;
}
for (const a of gen()) console.log(a); // 1,2,3
제너레이터를 통해 홀수만 순회하는 코드 작성
function* infinity(i) {
while (true) yield i++;
}
function* limit(l, iter) {
for (const a of iter) {
yield a;
if (a == l) return;
}
}
function* odds(l) {
for (const a of limit(l, infinity(1))) {
if (a % 2) yield a;
}
}
for (const a of odds(40)) log(a);
for…of, 전개 연산자, 구조 분해, 나머지 연산자
- Iterable, Iterator 프로토콜을 지키고 있는 것들을 통해 사용자 정의 이터레이터 활용
log(...odds(10));
log([...odds(10), ...odds(20)]);
const [head, ...tail] = odds(5);
log(head);
log(tail);
const [a, b, ...rest] = odds(10);
log(a);
log(b);
log(rest);
느낀점
제너레이터를 통해 순회할 수 있도록 코드를 작성할 수 있더나느 사실과 일반적인 순회가 아닌 특정 조건을 부여해 순회가 가능하다는 사실이 재밋게 다가왔다. 이를 통해 조금 더 효율적으로 순회할 수 있다는 사실을 알게되어서 좋았다.
참고
유인동님의 함수형 프로그래밍과 JS ES6+ 강의