HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
🐣
프론트엔드 데브코스 3기 교육생
/
📚
3기 스터디 가이드
/
🧑‍💻
CS 학습 및 면접대비 스터디
/
🎳
이터러블, 이터레이터 프로토콜
🎳

이터러블, 이터레이터 프로토콜

URL
발표자
명재
과목
Javascript
용어 정리이터러블, 이터레이터 이터러블(iterable)이터레이터(iterator)[Symbol.iterator]이터러블 구현하기이터러블이 순회하는 과정이터러블, 유사 배열 객체직접 구현한 이터러블, 유사 배열 객체의 문제점Array.from
 

용어 정리

  • 컬렉션: 컬렉션 자료형이란 여러 가지 요소를 하나로 묶어 사용하는 데이터 타입입니다.
  • 프로토콜: 프로토콜은 컴퓨터 내부에서, 또는 컴퓨터 사이에서 데이터의 교환 방식을 정의하는 규칙 체계입니다.
 

이터러블, 이터레이터

이터러블(iterable)

  • 이터러블의 정의는 Symbol.iterator를 프로퍼티 키로 사용한 메서드를 직접 구현하거나 프로토타입 체인을 통해 상속받은 Symbol.iterator 메서드를 호출하면 이터레이터 객체를 반환하는 객체입니다.
  • 이터러블 정의를 따르는 규약을 이터러블 프로토콜이라고 지칭합니다.
  • 이터러블은 for … of 문으로 순회할 수 있으며, 스프레드 문법과 배열 디스트럭처링 할당의 대상으로 사용할 수 있습니다.
  • 대표적인 빌트인 이터러블은 Array, TypeArray, String, Set, Map, DOM 컬렉션, arguments 가 있습니다.
console.log(Symbol.iterator in Array.prototype); // true console.log(Symbol.iterator in String.prototype); // true console.log(Symbol.iterator in Map.prototype); // true console.log(Symbol.iterator in Set.prototype); // true console.log(Symbol.iterator in Object.prototype); // false

이터레이터(iterator)

  • 이터레이터의 정의는 { done: boolean, value: 값} 형태의 객체를 반환하는 next 메서드를 가진 객체입니다. 또한 이터레이터는 Symbol.iterator의 반환값입니다.
  • 이터레이터 정의를 따르는 규약을 이터레이터 프로토콜이라고 지칭합니다.
const iterator = [1, 2, 3][Symbol.iterator](); console.log('next' in iterator); // true console.log(iterator.next()); // { value: 1, done: false }
🔑
이터레이션 프로토콜은 순회 가능한 데이터 컬렉션 자료구조를 만들기 위해 ES6 사양에 정의된 약속된 규칙입니다.
 

[Symbol.iterator]

위의 설명에서 [Symbol.iterator]라는 용어가 자주 등장했습니다. [Symbol.iterator] 는 이터러블을 구현하기 위해 이터레이션 프로토콜에서 정의한 규칙입니다. [Symbol.iterator]를 사용해서 직접 이터러블을 구현해봅시다.

이터러블 구현하기

const range = { from: 1, to: 5, }; range[Symbol.iterator] = function () { return { current: this.from, last: this.to, next() { if (this.current <= this.last) { return { done: false, value: this.current++ }; } else { return { done: true }; } }, }; }; for (const number of range) { console.log(number); // 1, 2, 3, 4, 5 }
  1. range 객체를 이터러블로 구현하기 위해서는 [Symbol.iterator] 메서드를 추가해야 합니다.
  1. 이터러블을 만들기 위해서는 [Symbol.iterator] 메서드는 이터레이터를 반환해야 합니다. 즉 next 메서드를 가지고 있는 객체를 반환해야 합니다.
  1. 이터레이터를 만들기 위해서는 { done: boolean, value: 값} 형태의 객체를 반환해야 합니다. (반복해서 구하고 싶은 값에 대한 특정한 조건문 추가)
  1. range 객체가 이터러블인지 확인하기 위해서 for ... of 를 통해 확인합니다.
 
직접 이터러블을 만들어보는 과정을 거치면서 확실하게 알게 된 점이 있습니다. 그것은 바로 이터러블을 구현하기 위해서는 이터레이터 프로토콜과 이터러블 프로토콜을 조합해야 합니다. 또한 명확히 보이는 부분은 ranage 객체는 이터러블이고 [Symbol.iterator]가 반환하는 객체가 이터레이터라는 점도 알 수 있습니다.
// range 자체를 이터레이터로 만들면 코드가 더 간단해집니다. let range = { from: 1, to: 5, [Symbol.iterator]() { this.current = this.from; return this; }, next() { if (this.current <= this.to) { return { done: false, value: this.current++ }; } else { return { done: true }; } } }; for (let num of range) { alert(num); // 1, then 2, 3, 4, 5 }

이터러블이 순회하는 과정

  1. for...of가 시작되자마자 for...of는 [Symbol.iterator]를 호출합니다.
  1. 이후 for...of는 반환된 객체(이터레이터)만을 대상으로 동작합니다.
  1. for...of에 다음 값이 필요하면, for…of는 이터레이터의 next 메서드를 호출합니다.
  1. next()의 반환 값은 {done: Boolean, value: any}와 같은 형태이어야 한다. 그래야 순회가 된다. done = true는 반복이 종료되었음을 의미한다. done = false일땐 value에 다음 값이 저장됩니다.
 

이터러블, 유사 배열 객체

  • 이터러블: 이터러블 프로토콜 조건을 충족하는 객체입니다.
  • 유사 배열 객체: 인덱스와 length 프로퍼티를 가지고 있는 객체로 배열처럼 동작하지만 배열이 아닙니다.
const lkeArray = { 0: 10, 1: 20, 2: 30, length: 3, }; for (const value of likeArray) { console.log(value); } // TypeError: likeArray is not iterable
예시의 likeArray 객체는 유사 배열 객체 조건에는 충족하지만 이터러블 프로토콜 조건에는 충족하지 못합니다.

직접 구현한 이터러블, 유사 배열 객체의 문제점

  • 직접 구현한 이터러블과 유사 배열은 실제 배열이 아닙니다.
  • 이런 문제로 Arrray.prototype을 통한 상속 메서드(map, filter)를 사용할 수 없습니다.
  • 그렇다면 어떻게 해결할 수 있을까요?

Array.from

Array.from메서드는 유사 배열 객체나 이터러블을 얕게 복사해 새로운Array 객체를 만듭니다.
const likeArray = { 0: 10, 1: 20, 2: 30, length: 3 }; console.log(Array.from(likeArray)); // [10, 20, 30] const arr = Array.from(likeArray); for (const value of arr) { console.log(value); // 10 20 30 }