iterable 객체

345·2023년 3월 25일

모던 JavaScript

목록 보기
11/23

🔔 iterable 객체란❓

iterable 이란 "반복 가능하다" 는 뜻으로, for..of 반복문을 적용 가능한 객체입니다.
대표적으로 배열과 문자열이 iterable 합니다.

  • iterable
    • for..of 반복문 사용 가능
    • 배열, 문자열
      • 배열의 각 요소 순회
      • 문자열의 각 글자 순회

✅ iterable 로 만들기

배열과 문자열 등 이터러블이 아니어도 for..of 문법을 사용하도록 할 수 있습니다.
배열이 아닌 객체가 for..of 를 사용하기 위해 다음과 같은 동작을 구현하면 됩니다.

  • for..of 사용시 이터레이터(메서드 next 가 있는 객체) 반환
  • for..of 는 이터레이터를 가지고 동작
  • for..of 의 다음 반복문의 값은 next() 메서드를 호출하여 얻음
  • next() 의 반환 값은 {done: Boolean, value: any} 형태
    • done=true: 반복문 종료
    • done=false: 반복문을 계속 진행, value 에 다음 값 저장

이를 위해 Symbol.iterator 를 사용합니다.
객체는 for..of 반복문 시작 시 Symbol.iterator 를 호출합니다.

Symbol.iterator

객체에 Symbol.iterator 라는 메서드를 추가합니다.
이 메서드는 이터레이터를 반환하며 next() 메서드를 정의합니다.

  • next() 메서드
    • 반복 진행 여부 정의
    • 반복문에 들어갈 value 정의
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
}

Symbol.iterator 가 반환한 객체와 그 객체의 메서드 next() 를 사용하여 반복문을 진행합니다.


for..of 반복문은 결국 이터레이터 객체가 next() 를 이용한다는 것이 핵심입니다.
새로운 객체를 반환하는 게 아니라 기존의 객체에서 next() 를 정의하고 기존 객체 자체를 반환할 수도 있습니다.

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
}

그러나, 새로운 이터러블 객체를 생성했던 위와 달리 range 객체 자체를 이터러블로 사용하고 있으므로, 하나의 객체가 동시에 for..of 반복문을 여러 개 사용할 수 없습니다.
같은 객체이므로 반복 상태를 공유하기 때문입니다.


✨ 이터러블과 유사 배열

이터러블과 유사 배열은 서로 구분됩니다.

  • 이터러블 : Symbol.iterator 가 구현된 객체, for..of 사용 가능
  • 유사 배열 : 인덱스와 length 프로퍼티가 있어 배열처럼 보이는 객체

유사 배열이라고 해서 이터러블인 것은 아니고, 이터러블이라고 해서 배열인 것도 아닙니다.
그러나 Array.from 메서드를 사용하면 이터러블이나 유사 배열을 배열로 만들어줄 수 있습니다.

Array.from

Array.from 은 유사 배열이나 이터러블 객체를 받아 새로운 Array 를 반환합니다.

Array.from(arrayLike[, mapFn[, thisArg]])
  • arrayLike : 유사 배열 혹은 이터러블
  • mapFn : 모든 배열 요소에 적용하는 맵핑 함수
  • 반환 값 : 새로운 Array

인덱스와 length 가 있는 유사 배열과 Symbol.iterator 를 구현한 객체의 경우를 배열화합니다.

profile
기록용 블로그 + 오류가 있을 수 있습니다🔥

0개의 댓글