모던 자바스크립트 입문(아소 히로시, 길벗, 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' 를 순서대로 표시한다.