본문 바로가기
공부/JavaScript

Iterator / Generator

by svcbn 2024. 11. 18.

09/19

 

Iterator

Iterator 는 next 메서드를 가지고 있는 객체.
이 메서드는 순차적으로 원소들을 탐색하며, next 메서드의 호출 시 마다 새로운 객체를 반환한다.

반환되는 객체는 value 와 done 프로퍼티를 가지고 있으며, 탐색이 완료될 때 done = true 가 된다.
대부분의 Iterator의 경우 탐색이 완료될 때 value를 생략하는 편.

let arr = [1, 2, 3];
let iter = arr[Symbol.iterator]();

console.log(iter.next());		// Object {value: 1, done: false}
console.log(iter.next());		// Object {value: 2, done: false}
console.log(iter.next());		// Object {value: 3, done: false}
console.log(iter.next());		// Object {value: undefined, done: true}

 

Iterable Object

기본적인 Iterable 객체/타입 으로는

1. Array
2. Set
3. Map - 원소들을 key/value 쌍으로 탐색.
4. DOM NodeList - Node 객체들 탐색.
5. primitive string - 각 유니코드별로 탐색.

Array, Set, Map 의 아래 메서드들은 Iterator 를 반환한다.
1. entries - key,value 쌍 [key, value]
2. keys
3. values

이 메서드들에서 반환되는 객체는 Iterable 이면서 Iterator 이다.
Array 에서 key 는 인덱스를 나타내며, Set 에서는 key, value 가 둘 다 value로 같다.
커스텀 객체의 경우는 Symbol.iterator 메서드를 추가해서 iterable이 될 수 있다.

 

Iterable Consumers

for - of loop, spread Operator, Positional Destruction 문법은 Iterable을 사용한다.

>> for - of loop <<
for (const value of someIterable) {
	// ...
}

>> spread Operator <<
// Iterable의 모든 value들이 arr에 추가
let arr = [firstElem, ...someIterable, lastElem];

// Iterable의 모든 value들이 arguments에 추가
someFunction(firstArg, ...someIterable, lastArg);

>> Positional Destruction <<
// Iterable의 첫 3개 값들 저장
let [a, b, c] = someIterable;

 

 

Generator

Generator 는 Iterable 이면서 Iterator인 객체의 특별한 종류로,
일시정지와 재시작 기능을 여러 반환 포인트들을 통해 사용할 수 있다.

yield 키워드를 통해 반환 포인트들을 구현 할 수 있으며, 오직 Generator 함수에서만 사용할 수 있다.
next 를 호출 할 때마다 다음 yield의 expression 이 반환되는 식.

yield value 를 사용하면 한가지 값을 반환할 수 있고,
yield* iterable 을 사용하면 해당되는 Iterable 의 값들을 순차적으로 반환시킬 수 있다.

Generator 의 반복이 끝나는 시점은 3가지 경우로,
1. generator 함수에서 return 사용
2. 에러 발생
3. 함수의 끝부분까지 모두 수행된 이후
이때 done 프로퍼티가 true 가 된다.

이러한 generator 함수는 Generator 객체를 반환하며, function* 키워드로 정의할 수 있다.
또는 클래스에서 메서드 이름 앞에 *을 붙여 정의할 수도 있다.

(C# 식 비유를 해보자면 IEnumerator 와 같은 역할을 하는 것 같음)

 

Generator Methods

next (value)
이 메서드는 다음 값을 얻는 역할을 하며, optional argument를 받는다는 점이 iterator과 다르다.
이 매개변수는 바로 이전의 yield [expression] 의 반환값으로 사용된다.

function* fibonacci() {
	let fn1 = 1;
    let fn2 = 1;
    while (true) {
    	let current = fn2;
        fn2 = fn1;
        fn1 = fn1 + current;
        
        let reset = yield current;
        console.log('reset', reset);
        if (reset) {
        	fn1 = 1;
            fn2 = 1;
        }
    }
}

let sequence = fibonacci();
console.log(sequence.next().value);		// 1
console.log(sequence.next().value);		// 1
console.log(sequence.next().value);		// 2
console.log(sequence.next().value);		// 3
console.log(sequence.next().value);		// 5
console.log(sequence.next().value);		// 8
console.log(sequence.next(true).value);		// reset = true >> yield 1
console.log(sequence.next().value);		// 1
console.log(sequence.next().value);		// 2
console.log(sequence.next().value);		// 3

return (value)
이 메서드는 매개변수로 온 값을 value로 반환하고, Generator 를 종료시킨다.
{ value: value, done: true}

throw (exception)
이 메서드는 인자로 받은 에러를 발생시키고, Generator 를 종료시킨다.
generator 함수 내부의 catch 를 통해 처리할 수도 있으며, 이 경우 종료되지 않는다.

'공부 > JavaScript' 카테고리의 다른 글

import / export  (0) 2024.09.23
ECMAScript (ES)  (0) 2024.09.23
Callback, Promise, Async, Await  (0) 2024.09.09
문자열 자르기  (1) 2024.09.09
Array Sort(), Filter()  (1) 2024.09.08