F.E/JavaScript

[JavaScript] 이터러블(interable), 이터레이터(iterator), 제네레이터(Generator)

pinomaker 2022. 8. 19. 09:42

이터러블(interable)

이터레이터를 리턴하는 [Symbol.iterator] 메소드를 가지고 있는 자료를 반복할 수 있는 객체다.

 

우리가 많이 사용하는 배열도 이터러블이며, 이터러블은 for of문으로 순회 할 수 있다.

만약 [Symbol.iterator] 메소드를 제거한다면, for of문으로 순회 할 수 없게 된다.

 

const arr = [1, 2, 3]
for(const a of arr) console.log(a) // 1, 2, 3

//[Symbol.iterator]를 없애본다면?
arr[Symbol.iterator] = null
for(const a of arr) console.log(a) // ERROR

 

이터레이터(iterator)

이터러블 객체의 [Symbol.iterator] 메소드를 호출하면 이터레이터 객체를 반환한다.

반환된 이터레이터 객체는 next 메소드를 소유하고 있고, 이 메서드를 호출할 때, {value : 값 , done : true/false} 형태의 이터레이터 객체를 반환하게 된다.

 

value는 현재 순회 값을 가지고 있고, done은 순회 종료 여부를 boolean 타입으로 알려준다. 즉 모든 요소를 순회하면 value는 undefined, done은 true가 되고 순회가 종료된다.

const arr = [1,2,3]
const iter = arr[Symbol.iterator]();
 
iter.next() //{value:1,done: false}
iter.next() //{value:2, done: false}
iter.next() //{value:3, done: false}
iter.next() //{value: undefined, done: true}

 

이터러블을 for of 등의 전개 연산자등과 함께 동작하도록하는 규약을 이터러블, 이터레이터 규약(interable/ iterator Protocol)이라고 한다.

 

사용자가 직접 프로토콜에 맞춰서 value와 done을 리턴하는 next 메소드를 return 하는 [Symbol.iterator] 메소드를 직접 작성하여 객체를 할당하거나, 제네레이터 함수를 이용하여 이터러블 객체를 생성할 수 있다.

 

(1) 직접 작성하여 이터러블 객체 생성

직접 순회할 횟수와, 이터레이터, next 메소드를 리턴한다.

const range = {
  from: 1,
  to: 5,
  [Symbol.iterator]() { 
    this.current = this.from
    this.last = this.to
    return this
  },
  next() {
      return this.current <= this.to ? { done: false, value: this.current++ } : { done: true }
  }
}
 
for (const a of range) console.log(a)

 

 제네레이터(Generator)

제너레이터는 함수로 이터러블 객체를 생성하는 함수이며, 화살표 함수로 선언이 불가능하다.

function* generator() { 
  yield 1; 
  yield 2;
  yield 3;
}

const generatorObj = generator()

for(const a of generatorObj) console.log(a)

 

객체를 전개하는 전개연산자도, 이터러블 규약을 따르고 있다.

const arr = [1, 2, 3]
const a = [...arr, ...[3, 4]]
console.log(a) // [1, 2, 3, 4, 5]

arr[Symbol.iterator] = null
const b = [...arr, ...[3, 4]]
console.log(b) // ERROR