Search

31장 이터러블(Iterable)

대분류
언어
서적
소분류
JS DeepDive
태그
이터러블
for...of
이터레이터
최종 편집 일시
2024/10/27 15:39
생성 일시
2024/02/08 00:16
14 more properties

이터레이션 프로토콜

ES6에서 도입
순회 가능한 데이터 컬렉션을 만들기 위한 규칙
이터레이션 프로토콜을 준수하는 이터러블은 for ... of문, 스프레드 문법, 배열 디스트럭처링 할당의 대상으로 사용 가능
이터레이션 프로토콜 종류
이터러블 프로토콜
Symbol.iterator 프로퍼티 키로 사용한 메서드를 직접 구현하거나 프로토타입 체인을 통해 상속받은 Symbol.iterator 호출 시 이터레이터 프로토콜을 준수한 이터레이터를 반환
--> 이터러블 프로토콜(for..of, 스프레드, 디스트럭처링 할당의 대상으로 사용 가능)
이터레이터 프로토콜
Symbol.iterator 메서드 호출 시 이터레이터 프로토콜을 준수한 이터레이터를 반환.
이는 next 메서드를 소유
next 메서드 호출 시 valuedone프로퍼티를 갖는 이터레이터 리절트 객체를 반환
이터레이터
이터레이터 프로토콜을 준수한 객체
이터러블 요소를 탐색하기 위한 포인터 역할!
[Symbol.iterator]() { ... } // --> 이터러블 // 위 Symbol.iterator가 return 시 아래의 이터레이터 반환 // 이터레이터 { next() { return { value: any, done: boolean }; // 이터러블 result 객체 } }
TypeScript
복사

이터러블

이터러블 인지 확인
const isIterable = v => v!== null & typeof v[Symbol.iterator] === 'function';
TypeScript
복사
배열은 Array.prototype으로 Symbol.iterator 메서드를 상속 받아 for ... of 문, 스프레드 문법, 배열 디스트럭처링 할당의 대상으로 사용 가능
Symbol.iterator를 직접 구현하지 않거나 상속받지 않은 일반 객체는 사용 불가

이터레이터

Symbol.iterator 메서드 호출 시 이터레이터를 반환하는데 이 이터레이터는 next 메서드를 갖는다.
next는 각 요소를 순회하기 위한 포인터의 역할.
next 메서드 호출 시 이터러블을 순차적으로 한 단계씩 순회하며 결과를 나타내는 이터레이터 리절트 객체 반환
리절트 객체의 value 프로퍼티는 현재 순회중인 이터러블 값을, done 프로퍼티는 이터러블 순회 완료 여부를 나타냄

빌트인 이터러블

빌트인 이터러블
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.prototype[Symbol.iterator]
DOM 컬렉션
NodeList, HTML.prototype[Symbol.iterator]

for ... of 문

for ... in 문 --> 객체의 프로토타입 체인상에 존재하는 모든 프로퍼티 중 [[Enumerable]] 값이 true인 프로퍼티를 순회하며 열거. (심벌 제외)
for .. of 문 --> 내부적으로 이터레이터의 next 메서드를 호출하여 이터러블 순회하며 next 메서드가 변환한 이터레이터 리절트 객체의 value 프로퍼티 값을 for ... of문 변수에 할당. (done이 true면 이터러블 순회 종료)

이터러블과 유사 배열 객체

유사 배열 객체는 이터러블이 아닌 일반 객체여서 Symbol.iterator 메서드가 없고, for ... of 문으로 순회 불가능

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

ES6 이전의 순회 가능한 데이터 컬렉션들은 통일된 규약 없이 for, for...in, forEach 등으로 다양한 방법으로 순회를 함. --> 이터레이션 프로토콜을 준수하는 이터러블로 통일해 for ... of, 스프레드, 배열 디스트럭처링 할당의 대상으로 사용할수 있도록 일원화(더 효율적이다)
이터레이션 프로토콜 : 데이터 소비자와 데이터 공급자를 연결하는 인터페이스 역할.

사용자 정의 이터러블

사용자 정의 이터러블 구현

피보나치 수열 사용자 정의 이터러블
const fibonacci = { [Symbol.iterator]() { let [pre, cur] = [0, 1]; const max = 10; return { next() { [pre,cur] = [cur, pre + cur]; return { value: cur, done: cur >= max }; } }; } }; for (const num of fibonacci) { console.log(num); }
TypeScript
복사

이터러블을 생성하는 함수

수열의 최대값을 인수로 전달받아 이터러블을 반환하는 함수로 만들면 된다.
const fibonacciFunc = function(max) { ... return { [Symbol.iterator]() { return {...}; } }; };
TypeScript
복사

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

이터레이터를 생성하려면 Symbol.iterator 메서드를 호출해야함
이터러블이면서 이터레이터인 객체
{ [Symbol.iterator]() { return this; }, next() { return { value: any, done: boolean }; } }
Plain Text
복사
이터러블이면서 이터레이터인 객체는 Symbol.iterator 메서드를 호출하지 않아도 next 메서드 사용 가능.
그러나 일반적인 이터러블인 객체는 next메서드를 사용하기 위해서는 const iterator = [Symbol.iterator](); 와 같이 한번 호출해야함

무한 이터러블 지연 평가

done 프로퍼티 생략시 무한 이터러블 생성 가능
이터러블은 지연 평가를 통해 데이터를 생성하므로 for ... of 문이나 배열 디스트럭처링 할당 등이 실행되기 이전까지 데이터 생성 X --> for ... of 의 경우 next 메서드 호출 전까지 데이터 생성 하지 않음
-> 불필요한 데이터를 미리 생성하지 않고 필요한 데이터를 필요한 순간에 생성하여 빠른 실행 속도, 불필요한 메모리 소비를 하지 않고 무한도 표현가능