iterable & iterator 프로토콜

minidoo·2021년 5월 2일
1
post-thumbnail

ES6 리스트 순회

const list = [1, 2, 3];
for(const a of list) {
    console.log(a);
}

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

  • 이터러블: 이터레이터를 리턴하는[Symbol.iterator]() 를 가진 값

  • 이터레이터: { value, done } 객체를 리턴하는 next()를 가진 값

  • 이터러블/이터레이터 프로토콜: 이터러블을 for...of, 전개 연산자 등과 함께 동작하도록 한 규약

const arr = [1, 2, 3];	// iterable
console.log(arr[Symbol.iterator]);	// ƒ values() { [native code] }

let iterator = arr[Symbol.iterator]();
iterator.next();	// {value: 1, done: false}
iterator.next();	// {value: 2, done: false}
iterator.next();	// {value: 3, done: false}
iterator.next();	// {value: undefined, done: true}

Array

const arr = [1, 2, 3];
console.log(arr[0]);	// 1

let iterator = arr[Symbol.iterator]();
iterator.next();

for(const a of iterator) {
    console.log(a);
}

Set

const set = new Set([1, 2, 3]);
console.log(set[0]);	// undefined

let iterator = set[Symbol.iterator]();
iterator.next();

for(const a of iterator) {
	console.log(a);
}

Map

const map = new Map([['a', 1], ['b', 2], ['c', 3]]);
console.log(map[0]);	// undefined

let iterator = map[Symbol.iterator]();
iterator.next();

for(const a of iterator) {
    console.log(a);
}

Array, Set, Map으로 리스트를 순회하려고 한다.
Array의 경우 인덱스로 접근 가능하지만, Set과 Map은 undefined 값이 나온다.

하지만 iterator을 순회했을 경우, 원하는 값을 얻을 수 있다. 즉, Array, Set, Map은 이터러블/이터레이터 프로토콜 규약을 따르는 것이다 :-)


Map의 경우 keys(), values(), entries() 를 통해서도 접근 가능하다.

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

사용자 정의 iterable

const iterable = {
    [Symbol.iterator]() {
        let i = 3;
        return {
            next() {
                return i == 0 ? { done: true } : { value: i--, done: false };
            },
            [Symbol.iterator]() { return this; }
        }
    }
};

let iterator = iterable[Symbol.iterator]();
for(const a of iterable) console.log(a);

전개 연산자

const list = [1, 2];
// list[Symbol.iterator] = null;	// list는 더 이상 iterable이 아님

console.log([...list, ...[3, 4]]);	// [1, 2, 3, 4];

전개 연산자 또한 iterable/iterator 프로토콜을 따르고 있는 값들을 펼칠 수 있다.

0개의 댓글