FrontEnd/JavaScript

도대체 이터레이터가 뭐야?

여행 가고싶다 2023. 7. 30. 15:54

대부분 리스트를 순회하는 코드를 작성해 보라고 하면 다음과 같이 작성한다.

const list = [1, 2, 3];

for (let i = 0; i < list.length; i++) {
		console.log(list[i])
	}
    
// 1
// 2
// 3
// undefined

 

하지만 ES6이후 새롭게 추가된 문법으로 위와 같은 코드를 조금 더 간결하고 직관적으로 표현할 수 있다.

const list = [1, 2, 3];

for (const a of list) console.log(a)
    
// 1
// 2
// 3
// undefined

그렇다면 Set 자료구조도 위와 같은 코드로 순회가 가능할까?

const set = new Set([1, 2, 3]);

for (const a of set) console.log(a)
    
// 1
// 2
// 3
// undefined

가능하다.

 

그렇다면 Map은?

const map = new Map([['a', 1], ['b', 2], ['c', 3]]);

for (const a of map) console.log(a)
    
// ['a', 1]
// ['b', 2]
// ['c', 3]
// undefined

역시 가능하다.

 

왜 이게 가능할까? 이를 이해하려면 이터러블과 이터레이터에 대한 이해가 필요하다.

 

이터러블, 이터레이터

이터러블 : 이터레이터를 리턴하는 [Symbol.iterator]() 를 가진 값
이터레이터: { value, done } 객체를 리턴하는 next() 를 가진 값

 

iterator라는 변수를 선언하고 list안에 있는 [Symbol.iterator]()을 할당해 보자.

 

그리고 iterator안에 next()의 값을 찍어보면 다음과 같다.

list

Set과 Map도 똑같이 console에 찍어보면,

set
map

이런 식으로 반환된다.

 

이터레이터는 { value, done } 을 반환한다는 것을 확인했다. 

 

위 코드에서 이터레이터가 value와 done을 반환한다는 내부적인 로직을 이해했다면 map함수를 이렇게 활용할 수 있다.

 

map 활용

 

그렇다면 이터러블을 생성한다면 더욱더 확장성 있는 코드를 작성할 수 있지 않겠는가?

 

이를 가능하게 해주는 것이 제너레이터이다.

 

제너레이터

제너레이터 : 이터레이터이자 이터러블을 생성하는 함수

 

제너레이터는 함수명 앞에 *을 붙여서 선언하면 된다.

 

간단한 제너레이터 함수는 다음과 같다.

 

이를 응용해서 홀수만 찾는 로직을 만들어 보면,

function *infinity(i = 0) {
  while (true) yield i++;
}

function *limit(l, iter) {
  for (const a of iter) {
    yield a;
    if (a === l) return;
  }
}
function *odds(l) {
  for (const a of limit(l, infinity(1))) {
    if (a % 2) yield a;
  }
}

for (const a of odds(10)) console.log(a);

// 1
// 3
// 5
// 7
// 9
// undefined

 

이 처럼 구현할 수 있다.

 

놀라운 건 

function *infinity(i = 0) {
  while (true) yield i++;
}

는 무한루프에 걸리지 않고 suspended 된다는 점이다.

 

 

 

참고한 사이트

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators

 

Iterators and generators - JavaScript | MDN

Iterators and Generators bring the concept of iteration directly into the core language and provide a mechanism for customizing the behavior of for...of loops.

developer.mozilla.org

 

 

 


 

마치며

 

자바스크립트의 iterator, generator에 대해 알아봤다.

 

JavaScript로 더 나은 코드, 버그 없는 코드, 확장성 높은 코드를 만들기 위해 더 좋은 개발자가 되기 위해선 꾸준히 공부하고 새로운 것을 받아들여야 한다. 특히 프런트엔드 개발자는 새로운 기술에 대해 더욱 유연해야 한다고 생각한다.

 

요즘 나의 코드들을 살펴보면 관성으로 작성했던 코드, 잘 돌아가는 코드를 작성하게 되는데 이러한 관성을 버리려고 노력하고 새로운 것들을 받아들여 많이 틀려보고 다시 고쳐보는 경험을 해야겠다.

 

끝.