이터러블 & 이터레이터

찌끅·2024년 7월 15일

이터러블(interable)

이터러블이란 자료를 반복할 수 있는 객체를 말하는 것이다.
우리가 흔히 쓰는 배열 역시 이터러블 객체이다.
그럼 만약 이 배열에게 이터러블 표식을 없애버리면 어떻게 될까?

let arr = [1,2,3]
for(const a of arr) console.log (a) // 정상작동 1,2,3


arr[Symbol.iterator] = null; // 이렇게 하면 순회가 되지 않는다
for(const a of arr) console.log (a) // Uncaught TypeError: arr is not iterable

멀쩡한 배열임에 불구하고 for..of로 순회할 수가 없게 되었다.

이터러블과 이터레이터

interable Protocal / iterator Protocal

정의: 이터러블을 [for..of], [전개 연산자], [비구조화] .. 등, 이터러블이나 이터레이터 프로토콜을 따르는 연산자들과 함께 동작하도록 하는 약속된 규약을 의미한다.
그래서 이터러블이란 이터러블 규약을 따르는 객체인 셈이다.

iterable

정의: 이터레이터를 리턴하는 Symbol.iterator 메서드를 가진 객체
배열의 경우 Array.prototype의 Symbol.iterator를 상속 받기 때문에 이터러블이다. 문자열도 마찬가지이다

iterator

정의: {value: 값, done: true/false} 형태의 이터레이터 객체를 리턴하는 next() 메서드를 가진 객체
next 메서드로 순환 할 수 있는 객체이다.
Symbol.iterator 안에 정의 되어있다.

const arr = [1,2,3]; //arr는 그냥 평범한 배열

const iter = arr[Symbol.iterator](); 
/*
문법 파헤치기 : key값을 문자열이 아닌 변수로 주기위해 arr[변수] 형태를 가진다.
위 사진에서 보듯이, Symbol.iterator 라는 key값을 가지고 value는 함수이다. 
이를 접근해서 함수실행() 시키면 이터레이터 객체가 반환되어 iter에 담기게 된다.
*/

iter.next()
//>{value:1,done: false}
iter.next()
//>{value:2, done: false},
iter.next()
//{value:3, done: false}
iter.next()
//{value: undefined, done: true}

[Symbol.iterator]

let range = { // 1) 객체 생성
  from: 1,
  to: 5
};


range[Symbol.iterator] = function() { // 2) 새로운 키:밸류 를 추가한다. 키는 변수형태, 밸류는 함수이다.

    return { // 객체를 리턴한다. 그런데 좀 특벽할 형태의 객체
      current: this.from,
      last: this.to,

      next() { // 3) next() 정의
        if (this.current <= this.last) {
          return { done: false, value: this.current++ }; 
          // 4) {value : 값 , done : true/false} 형태의 이터레이터 객체를 리턴합니다.
        } else {
          return { done: true };
        }
      }
    };
};

평범한 range 객체를 이터러블 객체로 만드는 과정이다.
1. 평범한 range 객체를 만든다.
2. 우리가 흔히 쓰는 개체에 새로운 key:value를 추가하고 싶을 때, range[key] = value를 통해 Symbol.iterator 키값과 밸류는 함수를 지정해 넣었다.

0개의 댓글