개인의 기록
  • 소개
  • 프로젝트
  • 글
  • 링크

© 2026 newgirok

← 함수형 자바스크립트

ES6 순회 — 이터러블·이터레이터 프로토콜

2024년 6월 27일
JavaScriptES6이터러블이터레이터

ES5까지는 for (var i = 0; i < arr.length; i++) 방식으로 순회했다. ES6부터는 for...of가 생겼는데, 이게 그냥 편의 문법이 아니라 이터러블·이터레이터 프로토콜이라는 명확한 규약 위에 만들어진 것이다.

for...of와 Symbol.iterator

Array, Set, Map은 모두 [Symbol.iterator]() 메서드를 가진다. for...of는 이걸 호출해서 이터레이터를 꺼내고, next를 반복 호출하며 순회한다.

const arr = [1, 2, 3];
let 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}

arr[Symbol.iterator] = null로 바꾸면 for...of가 TypeError를 던진다. for...of가 Symbol.iterator를 통해 동작한다는 증거다.

Set과 Map도 동일한 규약

Set은 인덱스 접근이 안 되지만 for...of는 된다. Map도 .keys, .values, .entries가 모두 이터러블을 반환한다.

const map = new Map([['a', 1], ['b', 2], ['c', 3]]);
for (const a of map.keys()) log(a);    // a b c
for (const a of map.values()) log(a);  // 1 2 3
for (const a of map.entries()) log(a); // ['a', 1] ...

사용자 정의 이터러블

이터러블 프로토콜을 직접 구현할 수도 있다.

  • 이터러블: [Symbol.iterator]()를 가진 객체
  • 이터레이터: {value, done} 객체를 반환하는 next를 가진 객체
const iterable = {
  [Symbol.iterator]() {
    let i = 3;
    return {
      next() {
        return i == 0 ? {done: true} : {value: i--, done: false};
      },
      [Symbol.iterator]() { return this; }
    };
  }
};

for (const a of iterable) log(a); // 3 2 1

이터레이터가 자기 자신을 [Symbol.iterator]()로 반환하면, 이터레이터 자체도 for...of로 순회할 수 있다. 이를 well-formed 이터러블이라고 한다.

전개 연산자도 이터러블 프로토콜을 따른다

const a = [1, 2];
const set = new Set([3, 4]);
const map = new Map([['k', 5]]);

log([...a, ...set, ...map.values()]); // [1, 2, 3, 4, 5]

for...of, 전개 연산자, 구조 분해 모두 같은 규약 위에 있다.

← 이전 글기본기 — 일급 함수와 고차 함수
다음 글 →제너레이터 — 이터러블을 만드는 함수