본문 바로가기
Study/JavaScript

You don't know JS yet(3-1) 이터레이션

by dailycoding777 2025. 2. 13.

 

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 같은 반복문에서 이터러블을 순회하는 핵심 원리

이터레이터가 중요한 사용 사례

  1. 지연(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 (더 이상 줄 게 없음)
    
    
  2. 무한 데이터 스트림 처리
    • 네트워크 요청을 통해 계속해서 데이터를 불러오는 경우
    • 대용량 로그 파일을 한 줄씩 읽어오는 경우
  3. 커스텀 데이터 순회
    • 데이터베이스의 결과를 하나씩 처리해야 할 때
    • 특정 조건에 따라 데이터를 불러오고 싶을 때

제너레이터란?

💡 제너레이터는 "필요할 때마다 값을 하나씩 뽑아주는 기계"

  • 한 번에 다 계산하지 않고, 필요할 때만 실행(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