
모던 자바스크립트 입문(아소 히로시, 길벗, 2018)을 공부하고 정리한 내용입니다.
이터레이션은 반복 처리라는 뜻으로 데이터 안의 요소를 연속적으로 꺼내는 행위를 말합니다.
예를 들어 배열의 forEach 메서드는 배열의 요소를 순차적으로 검색하여 그 값을 함수의 인수로 넘기기를 반복합니다.
let a = [1, 2, 3];
a.forEach((num) => { console.log(num) });
//결과
//1
//2
//3
이터레이터(iterator)란 반복 처리(iteration)가 가능한 객체를 말합니다. 위의 forEach 메서드의 작업은 내부적으로 처리되므로 개발자는 각 처리 단계를 제어할 수 없습니다.
그러나 ECMAScript 6부터 추가된 이터레이터를 사용하면 개발자가 반복 처리를 단계별로 제어할 수 있습니다.
ES6의 이터레이터는 일반적으로 다음 두 가지 항목을 만족하는 객체입니다.
let a = [1, 2, 3];
let iter = a[Symbol.iterator]();
// Symbol.iterator(이터레이터 심벌)는 이터레이터를 반환하는 메서드
console.log(iter.next()); // Object {value: 1, done: false}
console.log(iter.next()); // Object {value: 2, done: false}
console.log(iter.next()); // Object {value: 3, done: false}
console.log(iter.next()); // Object {value: undefined, done: true}
console.log(iter.next()); // Object {value: undefined, done: true}
function makeIterator(array) {
let index = 0;
return {
next() { // next 메서드
if ( index < array.length ) {
return {value: array[index++], done: false}; // next 메서드 반환값
} else {
return {value: undefined, done: true}; // next 메서드 반환값
}
}
};
}
const iter = makeIterator(['a', 'b', 'c']);
console.log(iter.next()); // Object {value: 'a', done: false}
console.log(iter.next()); // Object {value: 'b', done: false}
console.log(iter.next()); // Object {value: 'c', done: false}
console.log(iter.next()); // Object {value: undefined, done: true}
for/of 문은 다음 두 가지 조건을 만족하는 객체를 반복 처리합니다.
Symbol.iterator 메서드를 가진 객체를 반복 가능(이터러블, iterable)한 객체라고 합니다.
let a = [4, 5, 6];
let iter = a[Symbol.iterator](); // 변수 iter에 이터레이터 대입
while(true) {
let iteratorResult = iter.next();
if ( iteratorResult.done === true ) break;
let v = iteratorResult.value;
console.log(v); // 4 5 6 이 차례대로 console에 찍힘
}
위의 프로그램을 for/of 문을 사용하여 반복 처리를 자동으로 하도록 만들 수 있습니다. 아래의 프로그램은 위 프로그램과 같은 동작을 합니다
let a = [4, 5, 6];
for (let v of a) console.log(v); // 4 5 6 이 차례대로 console에 찍힘
이터레이터(iterator) 객체와 이터러블한(iterable) 객체는 서로 다른 개념의 객체입니다.
이터레이터는 next 메서드를 가지는 반면에, 이터러블한 객체는 Symbol.iterator(이터레이터 심벌) 메서드를 가지기 때문입니다.
상단의 배열의 이터레이터를 반환하는 함수 makeIterator로 생성한 iter는 이터레이터(iterator) 이지만 for/of 문으로는 순회할 수 없습니다. 왜냐하면 Symbol.iterator(이터레이터 심벌) 메서드를 가지고 있지 않아 이터러블(iterable)한 객체가 아니기 때문이죠.
for (let v of iter) console.log(v); // TypeError: iter is not iterable
주어진 이터레이터를 반복 처리하려면 다음과 같이 이터러블한(iterable) 객체를 생성해주어야 합니다.
즉 Symbol.iterator(이터레이터 심벌) 메서드를 추가하여 새로운 객체를 생성해야 합니다.
let iterable = {};
iterable[Symbol.iterator] = () => iter;
for (let v of iterable) console.log(v); // 'a' 'b' 'c' 를 순서대로 표시한다.