이 포스팅을 보기전에 이터러블에 관하여 먼저 이해하자.
자바스크립트에서 배열은 반복 가능한 객체(object)입니다. 반복이 가능하다는 것은 iterable이라고 부르기도 한다.
자바스크립트는 for of 반복문은 itrable 요소들만 순회할 수 있는 문법이다.
for of 반복문은 iterable 요소들만 반복할 수 있고 그렇지 않은 요소들로 반복하려고 할 때 TypeError: 요소 is not iterable 에러를 던진다. (for in 반복문은 일반 객체도 순회합니다!)
iterable
은 iterator를 리턴하는 [Symbol.iterator]()
를 가진 값, iterator
는 {value, done}
객체를 리턴하는 next() 를 가진 값
const iterable = {
[Symbol.iterator]() {
let i = 3;
return {
next(){
return i == 0 ? {done: true}:{value: i--, done:false};
},
[Symbol.iterator](){return this;} //자기자신을 return 해준다.
}
}
}
let iterator = iterable[Symbol.iterator]();
iterator.next(); // 주석 처리하며 비교해보자.
for(const a of iterator) console.log(a);
iterator를 리턴하는 iterable을 생성하는 함수이다.
function* 키워드를 사용해서 코드를 구현합니다.
yield 키워드를 사용해서 이터러블의 요소를 표현식으로 나타낼 수 있습니다.
// generator 함수로 이름은 gen이며 이터러블을 생성하는 함수
function* gen() {
yield 1;
yield 2;
yield 3;
return -1;
}
const iter = gen();
for (item of iter) console.log(item);
function *infinity(i = 0) {
while(true) yield i++;
}
function *limit(l, iter){
for(const value of iter) {
yield value;
if(value === l) return;
}
}
function* odds(l) {
for(const i of limit(l, infinity(1))) {
if(i % 2) yield i;
}
}
const iter = odds(10);
console.log(iter.next());
console.log(iter.next());
console.log(iter.next());
console.log(iter.next());
console.log(iter.next());
console.log(iter.next());
console.log(iter.next());
console.log(...odds(10));
console.log(...odds(10), ...odds(20));
const [head, ...tail] = odds(5);
console.log(head);
console.log(tail);
const [a, b, ...rest] = odds(10);
console.log(a);
console.log(b);
console.log(rest);