본문 바로가기
☁️ 구름 X kakao DeepDive/☁️ HTML CSS JS

[JavaScript] Iterator(반복기) & Generator(생성기)

by 뽀짜꼬 2025. 1. 9.
728x90
반응형


1. Iterator

Iterator 함수를 임의로 생성해보자

function makeIterator(numbers) {
    let nextIndex = 0;

    return {
        next: function () {
            return nextIndex < numbers.length ?
            {value: numbers[nextIndex++], done: false} :
            {value: undefined, done: true}
        }
    }
}

// 숫자 배열 생성
const numbersArray = [1,2,3];

const numbersIterator = makeIterator(numbersArray);

console.log(numbersIterator.next());
console.log(numbersIterator.next());
console.log(numbersIterator.next());
console.log(numbersIterator.next());

 

결과

Iterator는 value랑 done 속성을 가지는 객체를 반환한다.

[Symbol.iterator]() - 기본 이터레이터 반환 메소드

[Symbol.iterator]()을 사용하면 반복 가능한 값을 반복기로 생성 가능.

const numbersArray = [1,2,3];

const numbersIterator = numbersArray[Symbol.iterator]()

console.log(numbersIterator.next());
console.log(numbersIterator.next());
console.log(numbersIterator.next());
console.log(numbersIterator.next());

for..of 가 사용 가능하면 iterable 하다.

const numbersIterable = [1,2,3];
const numbersNotIterable = { a:1, b:2 };
console.log(typeof numbersIterable);
console.log(typeof numbersNotIterable);
for ( const n of numbersNotIterable ){
    console.log(n);
}

{ a:1, b:2 }는 for…of 를 사용할 수 없다 → iterable하지 않다.

다른것도 확인해보자

const set = new Set([1,2,3,4]);
console.log('set', set);

console.log(set[Symbol.iterator]());

const map = new Map([['a',1], ['b',2]])
console.log('map', map);
console.log(map[Symbol.iterator]());

console.log(set[Symbol.iterator]().next()); // 이렇게하면 이터레이터가됨.
console.log(map[Symbol.iterator]().next());

set과 map은 iterable함을 알 수 있다.


2. Generator 함수

사용자의 요구에 따라 다른 시간 간격으로 여러 값을 반환할 수 있다.

일반 함수 ⇒ 단 한 번의 실행으로 함수 끝까지 실행됨

제너레이터 함수 ⇒ 사용자의 요구에 따라 일시적으로 정지될 수도 있고, 다시 시작될 수도 있음.

Generator 함수를 직접 생성해보자

yield : 제너레이터 함수의 실행을 일시적으로 정지시킨다. 즉, 일반 함수의 return과 매우 유사하다.

제너레이터 함수를 만들때는 항상 *이 있어야 한다.

// 제너레이터 함수
function* sayNumbers() {
    yield 1;
    yield 2;
    yield 3;
}

// 제너레이터 함수의 반환이 제너레이터
const number = sayNumbers();

console.log(number.next());
console.log(number.next());
console.log(number.next());
console.log(number.next());

Generator 를 이용한 ID 생성

function* createIds() {
    let index = 1;

    while(true) {
        yield index++;
    }
}

 

>> Lazy Evaluation

계산의 결과값이 필요할 때 까지 계산을 늦춰서 필요한 데이터를 필요한 순간에 생성한다.

위의 코드가 Lazy Evaluation이다.

 

function* createIds() {
    let index = 1;

    while(true) {
        yield index++;
    }
}

const gen = createIds();

console.log(gen.next().value);
console.log(gen.next().value);
console.log(gen.next().value);

//억지로 값에 10을 넣어줄 수 있다.
console.log(gen.return(10));

Generator에서의 return

//억지로 값에 10을 넣어줄 수 있다.
console.log(gen.return(10));

yield에 *을 붙이면

function* generatorFunction() {
    yield* [1,2,3];
}

const generator = generatorFunction();

for (const number of generator) {
    console.log(number);
}

그냥 yield 1 yield 2 yield 3을 한것과 같다.

728x90
반응형