제너레이터/이터레이터
제너레이터 함수
- 제너레이터 객체 생성기
- 이터레이터이자 이터러블인 순회할 수 있는 값(제너레이터 객체)을 생성하는 함수
- well formed 이터레이터를 리턴하는 함수
- 제너레이터 함수가 리턴한 것이 이터레이터 이자 이터러블인 제너레이터 객체 임을을 유의
- 제너레이터 함수에
.next()
써봤자 안써진다!!
function* gen() { // yield로 몇번째에 뭐가 나올지도 정할수있다
yield 1;
if (false) yield 2;
yield 3;
}
let iter = gen(); // 이터레이터이자 이터러블을 반환
// 제너레이터 함수가 리턴한게 제너레이터 객체(유사 이터러블)임을 유의!!
log(iter[Symbol.iterator]() == iter); // true , well formed
log(iter.next());
log(iter.next());
log(iter.next());
log(iter.next());
for (const a of gen()) log(a); // 순회도 가능
// 제너레이터의 존재는 상당히 상징적
// 제너레이터를 통하면 정말 다양한 다형적인 값을들 순회할 수 있게 로직을 만들 수 있다
function* gen() { // yield로 몇번째에 뭐가 나올지도 정할수있다
yield 1;
if (false) yield 2;
yield 3;
}
let generator = gen(); // 이터레이터이자 이터러블을 반환
// 이터레이터
log(generator.next()); // {value: 1, done: false}
// 이터러블
let iterator = generator[Symbol.iterator]();
log(iterator.next()); // {value: 3, done: false}
// log([].next()) // 오류!! 보통 이터러블은 이터레이터가 아니다!!
odds 반환 제너레이터 함수 만들어보기
// 넘겨준 값으로 무한히 i를 늘려나가는 함수
// next 할때마다 1을 늘려서 리턴
// 무한이라도 next 할때만 실행된다
function* infinity(i = 0) {
while (true) yield i++; // 1 2 3 4 5.. 리턴값 무한대로 늘려간다
}
function* limit(length) {
for (const a of infinity(1)) {
// of 를 하면 next 를 계속친다, a에는 1 2 3 4 5.. 계속 들어간다
yield a; // 제너레이터 객체가 next 칠때마다 1 2 3 4 5.. 계속 리턴
if (a == length) return; // 다 되면 중단
}
}
function* odds(length) {
for (const a of limit(length)) {
if (a % 2) yield a;
}
}
let iter2 = odds(10); // iter2 가 제너레이터 객체 odds 는 제너레이터 함수
log(iter2.next());
log(iter2.next());
log(iter2.next());
log(iter2.next());
log(iter2.next());
log(iter2.next());
log(iter2.next());
for (const a of odds(40)) log(a);// 순회도 가능
for of, 전개 연산자, 구조 분해, 나머지 연산자