본 포스트는 인프런의 함수형 프로그래밍과 JavaScript ES6+ 강의(링크)를 듣고 정리한 내용입니다.


  • iterator이자, iterable을 생성(return)하는 함수
  • iter[Symbol.iterator]() == iter, 즉 자기 자신을 return하는 well-formed iterator
function *gen() {
  yield 1;
  yield 2;
  yield 3;
  return 100;
}
 
let iter = gen();
log(iter.next()); // {value: 1, done: false}
log(iter.next()); // {value: 2, done: false}
log(iter.next()); // {value: 3, done: false}
log(iter.next()); // {value: return, done: true}
 
for (const a of gen()) log(a); // 1 \n 2 \n 3
  • 일반 함수 앞에 '*' 표시를 붙여 만든다.
  • iterator이므로 next() method와 for of 문을 통한 순회도 가능
  • yield로 각 단계를 표시하고, return값은 done: true에 나오는 값

yield는 문장도 가능

yield 1;
if (false) yield 2;
yield 3;

이는 곧 어떠한 값도 순회할 수 있는 객체로 만들 수 있다는 말


홀수만 뽑는 generator odds를 만든다

function *adds(l) {
  for (let i=0; i<l; i++) {
    if (i % 2) yield i;
  }
}
let iter2 = odds(10);
log(iter2.next()); // {value: 1, done: false}
log(iter2.next()); // {value: 3, done: false}
log(iter2.next()); // {value: 5, done: false}
log(iter2.next()); // {value: 7, done: false}
log(iter2.next()); // {value: 9, done: false}
log(iter2.next()); // {value: undefined, done: true}
log(iter2.next()); // {value: undefined, done: true}

function *infinity(i = 0) {
  while (true) yield i++;
}
 
let iter3 = infinity();
iter3.next(); // {value: 1, done: false}
iter3.next(); // {value: 2, done: false}
iter3.next(); // {value: 3, done: false}
iter3.next(); // {value: 4, done: false}
  • iterator의 next를 평가할 때까지만 동작하므로 while문에 따른 오류는 없다.

function *infinity(i = 0) {
  while (true) yield i++;
}
 
function *odds(l) {
  for (const a of infinity(1)) {
    if (a % 2) yield a;
    if (a == l) return;
  }
}
 
let iter2 = odds(10);
log(iter2.next()); // {value: 1, done: false}
log(iter2.next()); // {value: 3, done: false}
...
log(iter2.next()); // {value: 9, done: false}
log(iter2.next()); // {value: undefined, done: true}
 
/////////////////////////////////////////////////////////////////
 
function *limit(l, iter) {
  for (const a of iter) {
    yield a;
    if (a == l) return;
  }
}
 
let iter4 = limit(4, [1, 2, 3, 4, 5, 6]);
log(iter4.next()); // {value: 1, done: false}
log(iter4.next()); // {value: 2, done: false}
log(iter4.next()); // {value: 3, done: false}
log(iter4.next()); // {value: 4, done: false}
log(iter4.next()); // {value: undefined, done: true}