3.1 이터레이션
일단 이 개념은 ES6부터 도입 되었다.
단어 의미 분석 실제 의미
이터러블 (Iterable) | Iter(반복) + able(가능) | 반복할 수 있는 객체 (for문에서 사용 가능) |
이터레이터 (Iterator) | Iter(반복) + or(~하는 것/사람) | 반복을 수행하는 객체 (next()로 값 꺼내는 역할) |
이터레이션 (Iteration) | Iter(반복) + ation(행위, 과정) | 반복하는 과정 자체 (for문 실행 과정) |
💡 즉,
- 이터러블(Iterable) = 반복 가능한 객체
- 이터레이터(Iterator) = 반복을 수행하는 객체
- 이터레이션(Iteration) = 반복 하는 행위, 과정
1.이터러블(Iterable) : 반복할 수 있는 객체
“반복할 수 있는 객체” , 즉 for...of 문에서 사용할 수 있는 객체
배열(Array) , 문자열(String) Set, Map 같은 자료구조가 대표적인 이터러블
1. 배열
const myArray = [10,20,30];
// for ...of 문을 사용해서 반복 가능 (이터러블이기 때문)
for (const num of myArray){
console.log(num) // 10,20,30
}
myArray 는 이터러블이기 때문에 for…of문에서 사용할 수 있다.
2.문자열
const myString = "Hello";
for (const char of myString) {
console.log(char); // H, e, l, l, o
}
2.이터레이터(Iterator) : 반복을 수행하는 객체
“반복을 수행하는 객체” , next()를 호출하면 다음 값을 반환함.
iterator.next() 를 호출할 때마다 값을 하나씩 꺼내줌.
const myArray = [10,20,30,]
const iterator = myArray[Symbol.iterator]();
console.log(iterator.next()); // { value : 10, done : false}
console.log(iterator.next()); // { value : 20, done : false}
console.log(iterator.next()); // { value : 30, done : false}
console.log(iterator.next()); // { value : 30, done : true} (끝남)
next() 함수란?
next()는 이터레이터에서 값을 하나씩 꺼내는 함수다.
이터레이터는 한 번에 하나의 요소만 반환하고, next()를 호출할 때마다 다음 값을 가져온다.
next() 를 호출할 때마다 값과 상태(done)를 반환한다.
- done : false : 아직 값이 남아 있음
- done : true : 모든 값을 소진 함
3. 이터레이션 (Iteration)
“이터러블을 순차적으로 탐색하는 과정” , 즉 for...of 같은 반복문이 실행되는 과정
next() 를 반복 호출하는 것이 이터레이션 과정이다.
const myArray = [100, 200, 300];
const iterator = myArray[Symbol.iterator](); // 이터레이터 생성
while (true) {
const result = iterator.next();
if (result.done) break; // 더 이상 값이 없으면 반복 종료
console.log(result.value); // 100, 200, 300
}
4.커스텀 이터레이터
const counter = {
start: 1,
end: 5,
current: 1,
[Symbol.iterator]() { // symbol.iterator를 구현하면 이터러블(반복가능한) 객체
return {
next: () => { // next()를 쓰면 이터레이터(반복 수행중인 객체)가 된다.
if (this.current > this.end) {
return { done: true }; // 끝나면 StopIteration
}
return { value: this.current++, done: false };
}
};
}
};
for (const num of counter) {
console.log(num); // 1, 2, 3, 4, 5
}
- symbol.iterator를 구현하면 이터러블 객체가 되고
- next()를 쓰면 이터레이터가 된다.
📌 최종 정리
개념 설명 JS 예제
이터러블 (Iterable) | for...of에서 반복 가능한 객체 | Array, String, Set, Map |
이터레이터 (Iterator) | next()를 호출해서 값을 하나씩 꺼낼 수 있는 객체 | const iterator = arr[Symbol.iterator](); |
이터레이션 (Iteration) | 이터러블을 이터레이터로 변환하고 next()를 호출하는 과정 | for...of, while(true) { next() } |
여기서부턴 내가 궁금한 점
1. Set과 Map의 이터러블 특징과 사용법
💡 Set과 Map도 이터러블(Iterable)한 객체라서 for...of 같은 반복문에서 사용할 수 있음.
A. Set 예제
✔️ Set은 중복되지 않는 유일한 값만 저장하는 자료구조
✔️ 배열(Array)과 비슷하지만, 중복 요소가 자동으로 제거됨
✔️ 순서가 보장되며, 요소 추가/삭제/확인 속도가 빠름
const mySet = new Set([10, 20, 30]);
for (const num of mySet) {
console.log(num); // 10, 20, 30
}
- set은 중복을 허용하지 않는 자료구조다.
- for..of 에서 자동으로 next() 를 호출하면서 값을 하나씩 꺼냄
B. Map 예제
✔️ Map은 키-값(key-value) 형태로 데이터를 저장하는 자료구조
✔️ Object와 비슷하지만 모든 타입의 키(key)를 허용
✔️ Object는 문자열/심볼만 키로 사용 가능하지만, Map은 함수, 객체 등도 키로 사용 가능
const myMap = new Map([
["a", 1],
["b", 2],
["c", 3]
]);
for (const [key, value] of myMap) {
console.log(key, value); // a 1, b 2, c 3
}
- Map은 키-값 쌍으로 저장하는 자료구조
- for...of 에서 [key,value] 로 구조분해 할당 가능
⇒ Map 도 이터레이터 변환해서 직접 next() 호출 가능!
const iterator = myMap[Symbol.iterator]();
console.log(iterator.next()); // { value: [ 'a', 1 ], done: false }
console.log(iterator.next()); // { value: [ 'b', 2 ], done: false }
console.log(iterator.next()); // { value: [ 'c', 3 ], done: false }
console.log(iterator.next()); // { value: undefined, done: true }
2. 이터러블은 언제 쓰는가?
“순회(반복)”이 필요할 때 사용한다.
- for...of 같은 반복문에서 활용
- Set , Map , Array , String 등은 이터러블 이기때문에 for...of 에서 바로 사용 가능
- 이터레이터를 사용하면 값을 하나씩 꺼내면서 처리하는 방식으로 반복문을 컨트롤 할 수 있음.
3. 이 문법은 무엇인가?
const iterator = myArray[Symbol.iterator](); // 이터레이터 생성
이터러블 객체(반복가능 객체) ⇒ 이터레이터(반복을 수행하는 객체)로 만들기 위한 함수다.
4."이터러블이 되는 반복문" vs "안 되는 반복문" 차이
💡 "이터러블이 되는 반복문"은 내부적으로 next()를 호출할 수 있어야 함!
💡 "이터러블이 안 되는 반복문"은 그냥 순서대로 돌리는 구조일 뿐, next() 개념이 없음!
반복문 내부적으로 next() 호출? 이터러블(Iterable) 필요? 사용 대상
for...of | ✅ 있음 | ✅ 필수 | Array, Set, Map, String |
for await...of | ✅ 있음 | ✅ 필수 | 비동기 이터러블 (async function*) |
forEach() | ❌ 없음 | ❌ 필요 없음 | Array 전용 |
map() | ❌ 없음 | ❌ 필요 없음 | Array 전용 |
for | ❌ 없음 | ❌ 필요 없음 | 배열, 숫자 등 |
while | ❌ 없음 | ❌ 필요 없음 | 조건이 참인 동안 실행 |
반복문 이터러블 필요 여부 사용 대상 특징
for...of | ✅ 필수 | 이터러블(Array, Set, Map, String 등) | 내부적으로 next() 호출하여 요소 순회 |
for await...of | ✅ 필수 | 비동기 이터러블 (async function*) | await을 포함한 비동기 반복 지원 |
5. 이터레이터는 중요한가?
메모리 효율성,성능 최적화,데이터 스트림 처리에 중요한 역할을 한다.
✅ 이터레이터를 따로 빼놓은 이유?
✔ next()를 직접 호출해서 메모리를 절약하면서 값 하나씩 불러오기 가능
✔ 대용량 데이터 처리 시 한 번에 모든 데이터를 로드하지 않고 필요한 만큼만 가져올 수 있음
✔ for...of 같은 반복문에서 이터러블을 순회하는 핵심 원리
✅ 이터레이터가 중요한 사용 사례
- 지연(lazy) 로딩
- 한 번에 모든 데이터를 가져오는 대신 필요할 때마다 하나씩 가져옴
- 예: 제너레이터 (Generator) 활용
// 제너레이터 코드임 function* pizzaGenerator() { yield "🍕 첫 번째 피자 조각!"; yield "🍕 두 번째 피자 조각!"; yield "🍕 세 번째 피자 조각!"; } const pizza = pizzaGenerator(); console.log(pizza.next().value); // 🍕 첫 번째 피자 조각! console.log(pizza.next().value); // 🍕 두 번째 피자 조각! console.log(pizza.next().value); // 🍕 세 번째 피자 조각! console.log(pizza.next().value); // undefined (더 이상 줄 게 없음)
- 무한 데이터 스트림 처리
- 네트워크 요청을 통해 계속해서 데이터를 불러오는 경우
- 대용량 로그 파일을 한 줄씩 읽어오는 경우
- 커스텀 데이터 순회
- 데이터베이스의 결과를 하나씩 처리해야 할 때
- 특정 조건에 따라 데이터를 불러오고 싶을 때
제너레이터란?
💡 제너레이터는 "필요할 때마다 값을 하나씩 뽑아주는 기계"
- 한 번에 다 계산하지 않고, 필요할 때만 실행(next())
- yield를 만나면 잠시 멈추고, 다음 next()가 실행될 때까지 대기
// 이해를 위해 한번 더 가져옴
function* pizzaGenerator() {
yield "🍕 첫 번째 피자 조각!";
yield "🍕 두 번째 피자 조각!";
yield "🍕 세 번째 피자 조각!";
}
const pizza = pizzaGenerator();
console.log(pizza.next().value); // 🍕 첫 번째 피자 조각!
console.log(pizza.next().value); // 🍕 두 번째 피자 조각!
console.log(pizza.next().value); // 🍕 세 번째 피자 조각!
console.log(pizza.next().value); // undefined (더 이상 줄 게 없음)
✅ 제너레이터 특징
특징 설명
지연 실행 (Lazy Execution) | next()를 호출할 때만 실행됨 |
메모리 절약 | 한꺼번에 계산하지 않고, 필요한 만큼만 생성 |
여러 번 값 반환 가능 | yield를 이용해 값 여러 개 반환 가능 |
제너레이터는 페이지네이션(API 통신)과 비슷하다.
📌 일반 페이지네이션 (서버 요청 많음)
ex ) A.서버 10개씩 주고 , B.프론트 2개씩 보여주기
각각 페이지네이션인거죠
[Client 요청] GET /api/data?page=1&limit=10 → 서버에서 10개 반환
[Client 요청] GET /api/data?page=2&limit=10 → 서버에서 10개 반환
[Client 요청] GET /api/data?page=3&limit=10 → 서버에서 10개 반환
📌 A (서버에서 10개씩 제공) → 페이지네이션
- 서버가 클라이언트 요청에 따라 limit=10씩 데이터를 반환
📌 B (프론트에서 2개씩 반환) → 제너레이터
- 프론트에서 10개 받은 데이터 중 next() 호출할 때마다 2개씩 반환
A (서버: 페이지네이션) vs B (프론트: 제너레이터) 차이점
구분 서버 | 서버 (페이지네이션) | 프론트 (제너레이터) |
데이터 제공 방식 | 요청할 때마다 10개씩 반환 | next() 호출할 때마다 2개씩 반환 |
메모리 사용량 | 서버에서 10개 데이터를 한 번에 제공 | 프론트에서 필요한 만큼만 처리 |
유용한 상황 | API 최적화, 데이터베이스 부담 줄이기 | 프론트엔드에서 필요한 만큼만 출력 |
'Study > JavaScript' 카테고리의 다른 글
You don't know JS yet(1장 4) (1) | 2025.02.20 |
---|---|
You don't know JS yet(3-2~4) 클로저,this,prototype (0) | 2025.02.13 |
You don't know JS yet(2) (0) | 2025.02.06 |
You don't know JS yet(1.5~1.8) (0) | 2025.01.23 |
You don't know JS (1.1~1.4) (0) | 2025.01.16 |