이터레이터(Iterator)

JaeungE·2021년 7월 18일
0

JavaScript

목록 보기
11/16
post-thumbnail

이전 포스팅인 확산 연산자와 구조 분해 할당에서 'Iterable 객체' 라는 말을 자주 사용했는데, 이번 포스팅에서 이터레이터를 통해 Iterable이 무엇인지 자세히 알아보려고 한다!😁





반복 가능한(Iterable)


Iterable 객체는 이터레이터(Iterator)를 이용해 객체의 요소들을 차례차례 가져올 수 있는 객체를 말한다.

배열이 가장 대표적인 Iterable 객체이므로, 배열을 예로 들어서 설명하겠다!


const arr = ['H', 'e', 'l', 'l', 'o'];
const it = arr.values(); // get iterator

for(let i = 0; i <= arr.length; i++){
    console.log(it.next());
  /*
   * { value: 'H', done: false }
   * { value: 'e', done: false }
   * { value: 'l', done: false }
   * { value: 'l', done: false }
   * { value: 'o', done: false }
   * { value: undefined, done: true }
   */
}

결과를 보면 배열을 순회하면서 요소를 출력하는데, 기존의 index 를 이용해 배열의 요소를 순회하는것이 아니라 arr.values() 메서드를 이용해 iterator를 얻어오고, next() 메서드로 배열을 순회하는것을 볼 수 있다!😲





이터레이션 프로토콜(Iteration protocol)


위에서 설명한 배열 말고도 Map, Set, String 처럼 다양한 Iterable 객체가 존재한다.

그런데 이미 정의되어있는 Iterable 객체 말고도 사용자가 임의로 어떤 객체를 Iterable 객체로 만들 수 있는 방법이 존재하는데, 그걸 가능하게 하는것이 바로 Iteration protocol이다!😆

자세한 내용은 아래에서 설명하도록 하고, 일단은 코드를 보고나서 이해하도록 하자!


const customIterable = {
  
    // Iteration protocol
    [Symbol.iterator] : function() {
        const arr = [1, 2, 3, 4, 5];
        let index = 0;

        return {
            next() {
                if(index < arr.length)
                    return { value : arr[index++], done : false };
                return { value : undefined, done : true};
            }
        }
    }
}

const it = customIterable[Symbol.iterator]();
let now = it.next();

while(!now.done) {
    console.log(now); /*
     		       * { value: 1, done: false }
     		       * { value: 2, done: false }
     		       * { value: 3, done: false }
     		       * { value: 4, done: false }
     		       * { value: 5, done: false }
     		       */
    now = it.next();
    
}

console.log(it.next()); // { value: undefined, done: true }

평범한 객체인데도 Iterable 객체처럼 동작이 가능한 것을 볼 수 있다. 이는 해당 객체가 Iteration protocol을 준수했기 때문이다.

Iteration protocolIterable protocolIterator protocol이 있다. 자세한 내용은 아래 설명을 참고하도록 하자!😊


Iterable protocol

Iterable protocol은 어떤 객체가 [Symbol.iterator]() 메서드를 가지고 있고, 해당 메서드를 호출 시 Iterator 를 반환하면 Iterable protocol을 준수했다고 할 수 있다.

Iterator protocol

Iterator protocol은 객체에 next() 메서드가 구현되어 있고, 해당 메서드가 { value : var, done : boolean } 형태의 객체를 반환하는 객체를 말한다. 이 객체를 Iterator 라고 부른다.


이렇게 Iteration protocol을 준수한 객체는 Iterable 객체라고 부를 수 있고, for ... of 반복문이나 전에 설명했던 확산 연산자 의 사용이 가능해진다!😮





끝나지 않는 Iterator


위에서 봤던 Iterator는 객체를 순회하다가 done : true로 마지막 요소라는 것을 알려주었다.
하지만 항상 done : false 로 만들어서 Iterator가 끝나지 않게 할수도 있다.

아래의 예제를 보도록 하자!


const twice = {
    [Symbol.iterator]() {
        let i = 1;

        return {
            next() {
                return { value : i *= 2, done : false};
            }
        }
    }
}

for(let num of twice) {
    if(num > 1024)
        break;
    console.log(num);
    /*
     * 2
     * 4
     * 8
     * 16
     * 32
     * 64
     * 128
     * 256
     * 512
     * 1024
     */
}

위 코드에서 if(num > 1024)break를 걸지 않았다면, num값이 Infinity가 나오더라도 계속해서 이전 값에 2를 곱해주는 연산을 계속해서 하게 된다.





참고 자료

[Iteration & for ... of | PoiemaWeb]
https://poiemaweb.com/es6-iteration-for-of

0개의 댓글