본 포스트는 인프런의 함수형 프로그래밍과 JavaScript ES6+ 강의(링크)를 듣고 정리한 내용입니다.
제너레이터
: 이터레이터이자 이터러블을 생성하는 함수function *gen() {
yield 1;
yield 2;
yield 3;
}
let iter = gen();
console.log(iter[Symbol.iterator]); //ƒ [Symbol.iterator]() { [native code] }
console.log(iter[Symbol.iterator]() == iter); //true
console.log(iter.next()); //{ value: 1, done: false }
console.log(iter.next()); //{ value: 2, done: false }
console.log(iter.next()); //{ value: 3, done: false }
console.log(iter.next()); //{ value: undefined, done: true }
for (const a of gen()) {
console.log(a);
}
//1
//2
//3
제너레이터
는 함수를 생성할때 앞에 *
을 붙인다.
well formed iterator
를 리턴하는 함수이다.
yield
를 통해 value
값을 생성할 수 있다.
return
값을 지정해 줄 수 있다.
function *gen2() {
yield 1;
yield 2;
yield 3;
return 200;
}
let iter2 = gen2();
console.log(iter.next()); //{ value: 1, done: false }
console.log(iter.next()); //{ value: 2, done: false }
console.log(iter.next()); //{ value: 3, done: false }
console.log(iter.next()); //{ value: 200, done: true }
for (const a of gen()) {
console.log(a);
}
//1
//2
//3
return
값은 done
이 true가 될때 나오는 값이다.제너레이터
는 순회할 값을 문장으로 표현하는 것이다.
function *gen() {
yield 1;
if (false) yield 2;
yield 3;
}
for (const a of gen()) {
console.log(a);
}
//1
//3
자바스크립트
에서는 제너레이터
를 통해 어떠한 값이나 상수도 순회할 수 있는 형태로 만들어준다.function *odds(l) {
for (let i = 0; i < l; i++) {
if (i % 2) yield i;
}
}
let iter3 = odds(10);
console.log(iter3.next()); //{ value: 1, done: false }
console.log(iter3.next()); //{ value: 3, done: false }
console.log(iter3.next()); //{ value: 5, done: false }
console.log(iter3.next()); //{ value: 7, done: false }
console.log(iter3.next()); //{ value: 9, done: false }
console.log(iter3.next()); //{ value: undefined, done: true }
제너레이터
를 만들어 보았다.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;
}
}
console.log(iter3.next()); //{ value: 1, done: false }
console.log(iter3.next()); //{ value: 3, done: false }
console.log(iter3.next()); //{ value: 5, done: false }
console.log(iter3.next()); //{ value: 7, done: false }
console.log(iter3.next()); //{ value: 9, done: false }
console.log(iter3.next()); //{ value: undefined, done: true }
infnity 제너레이터
를 만들어서 위의 코드와 똑같이 동작하게 만들어 보았다.function *limit(l, iter) {
for (const a of iter) {
if (a == l) return;
}
}
let iter4 = limit(4, [1, 2, 3, 4, 5, 6]);
console.log(iter4.next()); //{ value: 1, done: false }
console.log(iter4.next()); //{ value: 2, done: false }
console.log(iter4.next()); //{ value: 3, done: false }
console.log(iter4.next()); //{ value: 4, done: false }
console.log(iter4.next()); //{ value: undefined, done: true }
리미트 값과 iterable
을 받아 리미트 값까지만 iterable
을 출력해주는 제네레이터
를 만들어 보았다.
이 제네레이터를 이용하면 위의 코드를 더 재미있게 바꿀 수 있다.
function* odds(l) {
for (const a of limit(l, infinity(1))) {
if (a % 2) yield a;
}
}
let iter3 = odds(10);
console.log(iter3.next()); //{ value: 1, done: false }
console.log(iter3.next()); //{ value: 3, done: false }
console.log(iter3.next()); //{ value: 5, done: false }
console.log(iter3.next()); //{ value: 7, done: false }
console.log(iter3.next()); //{ value: 9, done: false }
console.log(iter3.next()); //{ value: undefined, done: true }
for (const a of odds(12)) {
console.log(a);
}
//1
//3
//5
//7
//9
//11
console.log(...odds(10)); //1 3 5 7 9
console.log([...odds(10), ...odds(20)]); //[ 1, 3, 5, 7, 9, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19 ]
const [head, ...tail] = odds(7);
console.log(head); //1
console.log(tail); //[ 3, 5, 7 ]
const [a, b, ...rest] = odds(10);
console.log(a); //1
console.log(b); //3
console.log(rest); //[ 5, 7, 9 ]