티스토리 뷰

이선 브라운의 러닝 자바스크립트 책을 학습하고 기억해둘 만 한 부분을 야생학습하여 정리하였습니다.

이터레이터와 제너레이터는 ES6에서 새로 도입되었습니다. 

이터레이터는 일종의 책갈피와 비슷한 개념입니다. 예를 들어 book이란 배열이 있고 이 배열의 각 요소는 책의 한 페이지를 나타내는 문자열이라고 칩시다.

const book = [ /* 문장 하나 씩 들어있는 문자열 배열 */ ];

// book 배열에 values 메서드를 써서 이터레이터를 만듭니다.
const it = book.values();

//이터레이터는 보통 it이란 이름으로 변수/상수 명을 짓습니다.

//읽기 시작
it.next();	// { value: /* book 배열의 첫번째 문장 */, done: false }
it.next();	// { value: /* book 배열의 두번째 문장 */, done: false }
it.next();	// { value: undefined, done: true }

 

이터레이터는 모두 독립적이기 때문에 새 이터레이터를 만들 때마다 처음부터 시작합니다. 또한 for ... of 루프를 사용하여 이터레이터 요소에 접근할 수 있습니다.

 

이터레이션 프로토콜

이터레이션 프로토콜은 모든 객체를 이터러블 객체로 바꿀 수 있습니다. 이터레이션 프로토콜은 클래스에 심볼 메서드 Symbol.iterator가 있고 이 메서드가 이터레이터처럼 동작하는 객체, 즉 value와 done 프로퍼티가 있는 객체를 반환하는 next 메서드를 가진 객체를 반환하면 그 클래스의 인스턴스는 이터러블 객체라는 뜻입니다.

class Log {
	constructor() {
    	this.messages = [];
    }
    add(message) {
    	this.messages.push({message, timestamep: Date.now()});
    }
    [Symbol.iterator]() {
    	return this.messages.values();
    }
}

//로그 클래스를 이터러블 객체로 만들어 for...of 루프로 순회합니다.
for(let entry of log) {
	console.log(`${entry.message + ${entry.timestamp}`);
}

//이터레이터를 직접 만들 수도, done에서 true를 반환하지 않는 무한한 데이터를 만들 수도 있습니다.
class FibonacciSequence {
	[Symbol.iterator]() {
		let a = 0, b = 1;
        return {
        	next() {
            	let rval = { value: b, done: false };
                b += a;
                a = rval.value;
                return rval;
            }
        };
    }
}

 

제너레이터

제네레이터란 이터레이터를 활용해 자신의 실행을 제어하는 함수입니다. 일반적인 함수와는 달리 두가지 새로운 개념을 가지고 있는데 첫째로는 제네레이터는 언제든 호출자에게 제어권을 넘길(yield)할 수 있습니다. 다음으로는 제네레이터는 호출한 즉시 실행되지 않고 대신 이터레이터를 반환하며 이터레이터의 next 메서드를 호출함에 따라 실행됩니다.

 

제네레이터를 만들 때는 function 키워드 뒤에 *을 붙입니다. 또한 return 외에 yield 키워드를 사용할 수 있습니다.

function* rainbow() {
	yield 'red';
	yield 'orange';
	yield 'yellow';
    //.....
}

const it = rainbow();
it.next(); // { value: "red", done: false }
//...

yield는 표현식이므로 반드시 어떤 값으로 평가되며 이를 이용하여 제너레이터와 호출자 사이에서 양방향 통신이 가능합니다.

function* interrogate() {
	const name = yield "What is your name?";
    const color = yield "What is your favorite color?";
    return `${name}'s favorite color is ${color}`;
}

const it = interrogate();
it.next();	// { value: "What is your name?", done: false }
it.next('Eraser');	// { value: "What is your favorite color?", done: false }
it.next('purple');	// // { value: "Eraser's favorite color is purple", done: false }

제너레이터에서 return 문을 사용하면 done은 true가 되고 value 프로퍼티는 return문이 반환하는 값이 되나, done이 true면 value 프로퍼티에 주의를 기울이지 않기 때문에 for...of 루프에서는 제대로 출력이 되지 않음을 감안하여 제너레이터에 return을 쓸 때는 반환값을 쓰지 않는 습관을 들이는 편이 좋습니다.

'Running JS 요약' 카테고리의 다른 글

JS - 비동기적 프로그래밍  (0) 2021.01.31
JS - 함수와 추상적 사고  (0) 2021.01.21
JS - 맵과 셋 / 예외와 에러 처리  (0) 2021.01.18
JS - 객체와 객체지향 프로그래밍  (0) 2021.01.11
JS - 배열  (0) 2021.01.06
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함