개발하다 보면 iterable, iterator라는 단어가 종종 나온다. “순회 가능한”, “순회시킬 때 사용하는 객체” 정도로 이해하고 있었는데, js에서 전개 문법(...)을 공부하다가 정확히 이해하고 싶어 찾아 봤다.

js에서 iterable과 iterator는 ECMAScript 2015(ES6)1에서 새로 도입한 프로토콜(내장 기능이나 문법이 아니라)이다. 물론 기본 구현돼 있는 객체도 있다. 프로토콜이 있으니 개발자가 모든 객체에 구현할 수 있다.

js에서 기본적으로 iterable하게 구현돼 있는 객체는 문자열(String), 배열(Array), Map, Set 같은 것들이다.

iterable하면 주어진 순서대로 데이터를 표현할 수 있다.

개략적인 프로토콜 설명

iterable한 객체에는 Symbol.iterator라는 프로퍼티가 있고, 이 프로퍼티에는 iterator를 리턴하는 함수가 할당돼 있다. 그래서 이 함수를 실행하면 iterator 객체가 나온다. 아래 예제를 참고해 보자.

// 배열은 기본적으로 iterable한 객체다.
const array = [1, 2, 3, 4];

// array의 Symbol.iterator 프로퍼티에 할당돼 있는 함수를 실행해 iterator 객체를 리턴받는다.
const iterator = array[Symbol.iterator](); 

iterator.next();
// 결과: Object { value: 1, done: false }

iterator.next();
// 결과: Object { value: 2, done: false }

iterator.next();
// 결과: Object { value: 3, done: false }

iterator.next();
// 결과: Object { value: 4, done: false }

iterator.next();
// 결과: Object { value: undefined, done: true }

위 예제에서 알 수 있듯, iterator 객체에는 next라는 메서드가 있다. 이 메서드를 실행하면 현재 커서의 위치에 따라 다음 요소의 값 리턴하면서(value) 순회이 완료됐는지 알려준다(done 키의 불리언 값).

iterable한 객체로 무엇을 할 수 있는가?

iterable하면 for ... of, ... 전개 문법, function* 선언, 구조 분해 할당을 사용할 수 있다.(참고)

기본 객체(Object)는 iterable하지 않지만, 프로토콜대로 Symbol.iterator 프로퍼티에 iterator 객체를 반환하는 함수를 구현해 iterable하게 만들면 위에서 나열한 기능들을 사용할 수 있게 된다.

참고

아래 링크들에서 더 자세한 내용을 볼 수 있다.

  1. ECMAScript 2015는 흔히 ES6라고 불리는 그 js 버전이다. 2015년 ES6 출시 이후에는 메이저 업데이트를 하지 않고 매년 개선해가는 식으로 js를 발전시키기로 했다고. 그래서 ES7이라는 말은 안 쓰고 이후 버전은 ECMAScript 2016, ECMAScript 2017 하는 식으로 부른다.