ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Javascript] Iteration Protocol
    Front-End(Web)/Javascript 2020. 12. 17. 20:45
    반응형

    🤔 서론

    for 반복문을 사용하던 중, 객체에서 for - in 은 key값을 반환하지만, for - of 문에선 value 값이 반환되지 않았다.

    또한, 'Uncaught TypeError: obj is not iterable' 라는 에러가 발생하는 것을 확인했다.

     

    for - of 문을 확실히 이해하려면, Iteration, Iterable, Iterator 에 관해 정리할 필요성을 느껴 별도 포스팅을 시작했다.


    📒 Iteration Protocol

     

    - Iteration(반복) (ES6 추가)

    이터러블 객체가 for - or문, 전개연산자(spread, ...) 등 순회동작 하도록 만든 규약을 Iteration Protocol 이라고 한다.

    혹은 모든 객체를 이터러블로 만들 수 있는 규약을 의미한다. 여기엔 Iterable Protocol, Iterator Protocol이 포함된다.

     

    - Iterable(이터러블)

    • 객체의 각 요소들을 반복할 수 있는 객체를 의미한다.
    • JS 자체에 내장된 객체(built-in objects)들이 포함된다. - Array, TypedArray, String, Map, Set, Arguments 등
    • Iterable 객체(자료형)들은, [Symbol.iterator]() 라는 함수가 내장되어 있다. 이 함수가 Iterator 를 반환해준다.
    • [Symbol.iterator]() 함수를 가진 객체는 iterable protocol을 만족하며, ES6에서 추가된 기능들을 사용할 수 있다.      * for - of 문, 전개연산자, 분해대입 등

    배열의 [Symbol.iterator]() 함수

     

    함수가 반환하는 Iterator

     

    - Iterator(이터레이터)

    • 이 객체는 next() 메소드를 포함하며, 이 next() 메소드를 통해서 순회동작이 가능한 것이다.
    • next() 메소드는 arguments가 없고, 반환값은 { value: 값, done: boolean } 객체이다. (반복이 끝나면 done: ture)
    • 위 두 가지 조건을 Iterator Protocol 이라고 하며, 이를 충족해야 이터레이터에 해당된다. 
    let str = 'hello'; 
    let iterator = str[Symbol.iterator](); 
    
    console.log(iterator); 			// {}
    console.log(iterator.next()); 	// { value: 'h', done: false }
    console.log(iterator.next()); 	// { value: 'e', done: false } 
    console.log(iterator.next()); 	// { value: 'l', done: false }
    console.log(iterator.next()); 	// { value: 'l', done: false }
    console.log(iterator.next()); 	// { value: 'o', done: false }
    console.log(iterator.next()); 	// { value: undefined, done: true }

    이처럼, 출발점 이터레이터는 빈 객체다. 그리고, 다음 객체부터 value는 현재 순서값, done은 반복 종료여부를 가진다.

    마지막으로, undefined 값과 함께 반복이 종료되었음을 확인할 수 있는 것이다. 

     

    <출처>
    mollang_k 님의 블로그 : https://mollangk.tistory.com/28
    香格里拉 님의 블로그 : https://kjwsx23.tistory.com/282
    Hello World Javascript : https://helloworldjavascript.net/pages/260-iteration.html

    📒 Generator Function

    직접 Iterable 자체를 만들기 위해 도입된 함수이다. Generator 함수는 Iterable 객체를 반환한다. (ES6 추가)

    Generator 함수를 선언하는 방법은 두 가지가 있다.

    // 1. GeneratorFunction
    
    const Generator1 = Object.getPrototypeOf(function*(){}).constructor;
    const gen1 = new Generator1('a', 'yield a * 2');
    const iterator = gen1(10);
    console.log(iterator.next());		// {value: 20, done: false}
    
    
    // 2. function*
    
    function* Generator2(start = 1, end = 10, step = 1) {
      for (let i = start ; i < end ; i += step) {
        yield i;
      }
    }
    // 등차수열 출력

    이 Generator 함수는 [Symbol.iterator]() 메소드를 가지고 있기에, iterable protocol을 만족한다고 할 수 있다.

    yield(return과 유사)는 순서대로 값들을 반환하며, 이 값이 iterator 들의 value 가 되는 것이다.

    • Generator 함수로부터 생성된 iterable 은 한 번만 사용될 수 있다. (built-in X)
    • Generator 함수 내부에서 정의된 일반함수(function) 에선 yield 키워드를 사용할 수 없다. (return 후 밖에서 yield)

    단순한 이터러블 오류에서, 정말 어려운 이론공부가 되었다...

    중요한 점은, 이같은 이유로 객체는 순회동작(for - of 문, spread 연산자)이 불가하기 때문에,

    key(), values() 메소드 등으로 대체된다는 점을 근본적으로 이해하게 된 유익한 포스팅이었다.

    반응형
Designed by Tistory.