nukw0n
찐이의 개발 연결구과
nukw0n
전체 방문자
오늘
어제
  • 분류 전체보기 (38)
    • 유연해지기 (21)
      • React.js (11)
      • Javascript (5)
      • webpack & babel (1)
      • etc. (4)
      • Next.js (0)
    • 단단해지기 (13)
      • Algorithm (9)
      • Computer Science (4)
    • 속닥속닥 (4)
    • 책읽는 남자 (0)

블로그 메뉴

    공지사항

    인기 글

    태그

    • sass vs postcss
    • Batching
    • 알고리즘
    • bfs
    • Auto Batching
    • fallback UI
    • javascript
    • 콜백 ref
    • useBuiltIns
    • 백준
    • vanilla spa
    • history API
    • dfs
    • intersectionobserver api
    • React 18
    • error 안 뜸
    • React
    • vallia 라우터
    • 프로그래머스
    • Error Boundary

    최근 댓글

    최근 글

    티스토리

    hELLO · Designed By 정상우.
    nukw0n

    찐이의 개발 연결구과

    [Javascript] Iterable, 반복자 그리고 생성자 함수에 대하여
    유연해지기/Javascript

    [Javascript] Iterable, 반복자 그리고 생성자 함수에 대하여

    2021. 9. 27. 17:24

     

    Iterable이란 ?

    자바스크립트에서 iterable이란 반복이 가능함을 의미한다.

     

    반복이 가능한 요소는 무엇이 있을까?

    배열, Map, Set 등 모두 iterable 한 요소이다.

     

    이러한 요소들이 iterable 한 것은 Iteration Protocol을 따르기 때문이다.

    Iteration Protocol 을 따름으로써 for ... of 구문이나 spread 문법 등을 사용할 수 있게 된다.

    Iteration Protocol이란?

    Object를 iterable하도록 만드는 표준방법을 제시하는 일종의 규약이다.
    이 프로토콜을 따라 iterator을 구현할 수 있다.

     

    Object가 iterable 하기 위해서는 @@iterator 메소드를 가지고 있어야 한다.

    이는 Object가 [Symbol.iterator] 라는 속성을 가지고 있어야 한다는 의미이다.

    Iterator의 조건

    또한 어떠한 Object가 iterator가 되기 위해서는 다음의 조건을 만족해야한다.

    {
        ...,
        next() {
            return {
                value: any,
                done: boolean,
            }
        }
    }

    value와 done을 반환하는 next라는 메서드를 가지고 있어야 한다.

     

    이 때,

    value는 iterator가 반환하는 어떠한 값을 의미한다.
    done은 iterator가 종료되었는가를 의미하는 boolean 값이다.

    Map의 iteration

    Map을 통해 iterator를 확인해보자.

    const myMap = new Map();
    myMap.add('a', 1);
    myMap.add('b', 2);
    myMap.add('c', 3);
    myMap.add('d', 4);
    
    const iter = myMap[Symbol.iterator](); // Map Iterator

    iter은 iteration protocol에 의해 next라는 메서드를 가지고 있을 것이다.

    iter.next(); // { value: [a, 1], done: false }
    iter.next(); // { value: [b, 2], done: false }
    iter.next(); // { value: [c, 3], done: false }
    iter.next(); // { value: [d, 4], done: false }
    iter.next(); // { value: undefined, done: true }
    for (const [key, val] of myMap) {
        console.log(key, val); // a 1, b 2, c 3, d 4
    }
    console.log([...myMap]); // [[a,1], [b,2], [c,3], [d,4]]

    커스텀 iterator

    앞에서 언급한 내용을 통해 커스텀 iterator을 만들어보자.

     

    다음과 같은 foo 객체가 있을 때, 값의 타입이 배열인 것만 출력하고 싶을 때의 iterator을 만들어보자.

    const foo = {
        bar: [1,2,3,4,5],
        toz: 'hello',
        kor: [5,6,7,8,9],
        mzp: () => 'func!',
    };

    next 함수 정의해서 구현

    function getIterator() {
        let valueIdx = 0;
        const fooValues = Object.values(foo);
        const iter = {
            next() {
                 while(!Array.isArray(fooValues[valueIdx])){
                     if (++valueIdx >= fooValues.length) {
                         return {
                             value: undefined,
                             done: true,
                         }
                     }
                 }
    
                 return {
                     value: fooValues[valueIdx++],
                     done: false,
                 };
    
            },
        };
    
        return iter;
    }
    
    
    const iter = getIterator();
    iter.next(); // { value: [1,2,3,4,5], done: false }
    iter.next(); // { value: [5,6,7,8,9], done: false }
    iter.next(); // { value: undefined, done: true }

    generator function 구현

    // 1번 방법
    foo[Symbol.iterator] = function* () {
        for (let key of Object.values(this)) {
            if (Array.isArray(key)) yield key;
        }
    }
    
    for (let val of foo) {
        console.log(val); // [1,2,3,4,5], [5,6,7,8,9];
    }
    
    
    // 2번 방법
    function *getIterator() {
        for (let key of Object.values(foo)) {
            if (Array.isArray(key)) yield key;
        } 
    }
    
    const iter = getIterator();
    for (let val of iter()) {
        console.log(val); // [1,2,3,4,5], [5,6,7,8,9];
    }
    
    
    next() 함수를 정의할 경우 인덱스 같이 현재 상태에 대한 정보를 가지고 있어야하는 반면
    생성자 함수 를 사용하면 훨씬 간단하게 구현할 수 있다.

    '유연해지기 > Javascript' 카테고리의 다른 글

    JavaScript Set 내 맘대로 구현하기  (1) 2022.11.30
    Vanilla Javascript로 간단한 SPA 라우터 구현해보기  (4) 2022.05.13
    [Javascript] Promise 예제 풀어보기  (0) 2021.09.12
    [Javascript] 자바스크립트 Map 정렬하기  (0) 2021.05.03
      '유연해지기/Javascript' 카테고리의 다른 글
      • JavaScript Set 내 맘대로 구현하기
      • Vanilla Javascript로 간단한 SPA 라우터 구현해보기
      • [Javascript] Promise 예제 풀어보기
      • [Javascript] 자바스크립트 Map 정렬하기
      nukw0n
      nukw0n
      프론트엔드 개발자 권혁진입니다.

      티스토리툴바