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}
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);
}
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);
}
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);
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 프로토콜을 따르고 있는 값들을 펼칠 수 있다.