728x90
iterable 객체란
반복 가능한(iterable, 이터러블) 객체는 배열을 일반화한 객체이다. 이터러블 이라는 개념을 사용하면 어떤 객체에든 for..of 를 사용할 수 있다.
배열은 대표적인 이터러블이다. 배열 외에도 다수의 내장 객체가 반복 가능하다. 문자열 역시 이터러블의 예시이다.
Symbol.iterator
직접 이터러블 객체를 만들어보자
예시의 객체 range는 숫자 간격을 나타낸다.
let range = {
from : 1,
to : 5
}
// 아래와 같이 for..of가 동작할 수 있도록 하는 게 목표입니다.
// for(let num of range) ... num=1,2,3,4,5
동작 원리
- for…of가 시작하자 마자 Symbol.iterator를 호출한다. Symbol.iterator는 반드시 이터레이터를 반환해야한다.
- 이후 for…of 는 반환된 객체만을 대상으로 동작한다.
- for…of 에 다음값이 필요하면 for..of는 이터레이터의 next() 메서드를 호출한다.
- next()의 반환값은 {done: Boolean, value: any}와 같은 형태여야 한다. done=true는 반복이 종료되었음을 알린다. done=true일땐 value에 다음 값이 저장된다.
range를 반복 가능한 객체로 만들어주는 코드는 다음과 같다.
let range = {
from: 1,
to: 5
};
// 1. for..of 최초 호출 시, Symbol.iterator가 호출됩니다.
range[Symbol.iterator] = function() {
// Symbol.iterator는 이터레이터 객체를 반환합니다.
// 2. 이후 for..of는 반환된 이터레이터 객체만을 대상으로 동작하는데, 이때 다음 값도 정해집니다.
return {
current: this.from,
last: this.to,
// 3. for..of 반복문에 의해 반복마다 next()가 호출됩니다.
next() {
// 4. next()는 값을 객체 {done:.., value :...}형태로 반환해야 합니다.
if (this.current <= this.last) {
return { done: false, value: this.current++ };
} else {
return { done: true };
}
}
};
};
// 이제 의도한 대로 동작합니다!
for (let num of range) {
alert(num); // 1, then 2, 3, 4, 5
}
이터러블 객체의 핵심은 ‘관심사의 분리’에 있다.
- range 에는 메서드 next()가 없다.
- 대신 range[Symbol.iterator]() 를 호출해서 만든 ‘이터레이터’ 객체와 이 객체의 메서드 next() 에서 반복에 사용될 값을 만들어 낸다.
이렇게 하면 이터레이터 객체와 반복 대상인 객체를 분리할 수 있다.
이터레이터 객체와 반복 대상 객체를 합쳐서 range 자체를 이터레이터로 만들면 코드가 더 간단해진다.
let range = {
from: 1,
to: 5,
[Symbol.iterator]() {
this.current = this.from;
return this;
},
next() {
if (this.current <= this.to) {
return { done: false, value: this.current++ };
} else {
return { done: true };
}
}
};
for (let num of range) {
alert(num); // 1, then 2, 3, 4, 5
}
반응형
'JavaScript 개념' 카테고리의 다른 글
문자열 (1) | 2024.04.30 |
---|---|
숫자형 (0) | 2024.04.29 |
원시값의 메서드 (0) | 2024.04.29 |
객체 (0) | 2024.04.29 |
테스트 자동화와 Mocha (0) | 2024.04.29 |