34장 이터러블

34.1 이터레이션 프로토콜

  • ES6에서 도입된 이터레이션 프로토콜(iteration protocol)은 순회 가능한(iterable) 데이터 컬렉션을 만들기 위해 ECMAScript 사양에 정의하여 미리 약속한 규칙이다.

  • EC6 이전의 순회 가능한 데이터 컬렉션(array, string, array-like, DOM collection 등)은 통일된 규약(protocol)없이 각자 나름의 구조를 가지고 for문, for…in문, forEach 메서드 등 다양한 방법으로 순회할 수 있었다.

  • 순회 가능한 데이터 컬렉션을 이터레이션 프로토콜을 준수하는 이터러블로 통일하였다.

  • ⭐️ 이터러블for…of 문, 스프레드 문법, 디스트럭처링의 대상으로 사용 가능하다.

  • 이터러블 프로토콜(iterable protocol)

    • Symbol.iterator를 프로퍼티 키로 사용하는 메서드를 직접 구현하거나 프로토타입 체인으로 상속받은 Symbol.iterator 메서드를 호출하면 이터레이터 프로토콜을 준수한 이터레이터(iterator)를 반환한다.(뒤에 예제에서 살펴볼 예정)

    • 이러한 규약을 이터러블 프로토콜이라고 한다. iterable-interface

  • 이터레이터 프로토콜(iterator protocol)

    • 이터러블의 Symbol.iterator 메서드를 호출하면 이터레이터 프로토콜을 준수한 이터레이터를 반환한다.

    • 이터레이터(iterator)는 next 메서드를 가지고 있다.

    • next 메서드를 호출하면 이터러블을 순회하여 valuedone 프로퍼티를 갖는 **이터레이터 리절트 객체(iteratorResult)**를 반환한다.

    • 이러한 규약을 이터레이터 프로토콜이라고 한다.

    • 이터레이터 프로토콜을 준수한 객체를 이터레이터라고 한다. iterator-interface iterator-result-interface

iteration-protocol

34.1.1 이터러블

  • 이터러블 객체 = 이터러블 프로토콜을 준수한 객체

  • 어떤 객체가 이터러블인지 확인하는 방법: Symbol.iterator 프로퍼티 키를 가지고 있는지 확인한다

34.1.2 이터레이터

  • 이터러블의 Symbol.iterator 을 호출하면 이터레이터 프로토콜을 준수한 이터레이터가 반환된다.

  • 반환된 이터레이터는 next 메서드를 갖는다.

  • next 메서드는 이터러블의 각 요소를 순회하기 위한 포인터 역할을 한다.

  • 즉, next 메서드를 호출할 때마다 이터러블을 순회하며 순회 결과로 이터레이터 리절트 객체(iterator result object)를 반환한다.

34.2 빌트인 이터러블

  • 자바스크립트는 이터레이션 프로토콜을 준수하는 객체인 빌트인 이터러블을 제공한다.

빌트인 이터러블
Symbol.iterator 메서드

Array

Array.prototype[Symbol.iterator]

String

String.prototype[Symbol.iterator]

Map

Map.prototype[Symbol.iterator]

Set

Set.prototype[Symbol.iterator]

TypedArray

TypedArray.prototype[Symbol.iterator]

arguments

arguments[Symbol.iterator]

DOM 컬렉션

NodeList.prototype[Symbol.iterator]

HTMLCollection.prototype[Symbol.iterator]

array-instance-method

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/@@iterator

34.3 for...of 문

  • for … of 문은 이터러블을 순회하면서 이터러블 요소를 변수에 할당한다.

  • for … in 문은 객체의 프로토타입 체인 상에 존재하는 모든 프로토타입의 프로퍼티 중에서 프로퍼티 어트리뷰트 [[Enumerable]]의 값이 true 인 프로퍼티를 순회하며 열거(enumeration)한다. 프로퍼티키가 symbol인 프로퍼티는 열거하지 않는다.

  • for … of 문 내부적으로 이터레이터의 next 메서드를 호출하여 이터러블을 순회한다.

    • next 메서드가 반환하는 이터레이터 리절트 객체의 value 값을 변수에 할당한다.

    • done 값이 false이면 순회하고 true이면 순회를 중단한다.

34.4 이터러블과 유사 배열 객체

  • 유사 배열 객체: 배열처럼 인덱스로 프로퍼티 값에 접근할 수 있고 length 프로퍼티를 갖는 객체

    • 아래 예제의 arrayLike와 같이 유사 배열 객체는 이터러블이 아니기 때문에 for … of 문을 사용할 수 없다.

  • Array.from 메서드를 사용해 배열로 간단하게 변환할 수 있다. (⭐️정말 유용함)

    • Array.from 사용 예시

34.5 이터레이션 프로토콜의 필요성

이터레이션 프로토콜을 준수하는 이터러블

Array, String, Map, Set, TypedArray(Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array), DOM data structure(NodeList, HTMLCollection), Arguments

iteration-protocol
  • 다양한 **데이터 공급자(Data provider)**가 각자의 순회 방식을 갖는다면 **데이터 소비자(Data consumer)**는 다양한 데이터 소스의 순회 방식을 모두 지원해야 한다.

  • 이는 효율적이지 않다. 하지만 다양한 데이터 공급자가 이터레이션 프로토콜을 준수하도록 규정하면 데이터 소비자는 이터레이션 프로토콜만을 지원하도록 구현하면 된다.

  • 이터레이션 프로토콜은 데이터 소비자와 데이터 공급자를 연결하는 인터페이스의 역할을 한다.

34.6 사용자 정의 이터러블

34.6.1 사용자 정의 이터러블 구현

  • 주석을 하나씩 보면서 이터러블 객체를 어떻게 구현하는지 확인할 수 있다.

  • 이터러블 객체는 for … of 문, 스프레드 문법, 디스트럭처링 할당에서 사용할 수 있다.

34.6.2 이터러블을 생성하는 함수

  • 위 예제를 보면 range 객체의 fromto 프로퍼티 값이 1과 10으로 각각 고정되어 있다.

  • rangefromto 값을 외부에서 전달받아 반환하는 함수를 만들면 된다.

34.6.3 이터러블이면서 이터레이터인 객체를 생성하는 함수

  • 앞서 살펴본 range 함수는 이터러블을 반환한다.

  • 이터레이터를 생성하려면 이터러블의 Symbol.iterator 메서드를 호출해야 한다.

  • 이터러블이면서 이터레이터인 객체를 생성하면 Symbol.iterator 메서드를 호출하지 않아도 된다.

34.6.4 무한 이터러블과 지연 평가

  • 무한 수열 구현 가능

  • 이터러블은 데이터 공급자의 역할을 한다.

  • 배열이나 문자열 등은 모든 데이터를 메모리에 미리 확보한 다음 데이터를 공급한다.

  • 하지만 이터러블은 **지연 평가(lazy evaluation)**을 통해 데이터를 생성한다.

  • 즉, 필요한 데이터를 필요한 순간에 생성하므로 빠른 실행 속도를 기대할 수 있고, 불필요한 메모리 소비를 하지 않는다.

Last updated