iterable 객체

Happhee·2022년 5월 5일
0

AvenJS

목록 보기
10/17

iterator를 생성해서 next()로 순회할 수 있는 자료구조인 iterable 객체에 대해 알아보자.


✨ iterable 객체

반복 가능한 객체는 배열을 일반화한 객체이다.
이터러블이라면 for ... of 가 적용된다.

배열이 대표적인 이터러블이고, 문자열도 이터러블이다.

✨ Symbol.iterator

이터러블로 만들기 위해 Symbol.iterator라는 메서드를 추가해 for ... of 가 동작되도록 한다.

👇 예제 코드를 보자.

let fruit = {
  name : "apple",
  minQuantity : 12,
  maxQuantity : 24
};

현재 fruit의 객체는 반복 가능한 객체가 아니다. 때문에 for ... of가 동작하지 않으며 이를 정상적으로 작동시키기 위해서는 Symbol.iterator를 사용해야 한다.

이를 통해 우리는 for ... of가 동작하기 위해서 Symbol.iterator가 필요하다는 사실을 알 수 있다.

👇 fruit를 iterable로 만들어보자.

fruit[Symbol.iterator] = function(){
  return {
    min : this.minQuantity,
    max : this.maxQuantity,
   
    next(){
      if(this.min <= this.max){
        return { done : false, value: this.min++};
      } else {
        return { done : true };
      }
    }
  };
};
for( const info of fruit) alert(info);
// 12, 13, 14 ... 23, 24

위의 코드에서 이터레이터와 반복 대상 객체를 분리해보면 다음과 같다.

let fruit = {
  name : "apple",
  minQuantity : 12,
  maxQuantity : 24,
  
  [ Symbol.iterator ] () {
    this.min = this.minQuantity;
    return this;
  },
  next() {
    if ( this.min <= this.maxQuantity){
      return { done : false, value : this.min ++ };
    } else {
      return { done : true };
    }
  }
};
for( const info of fruit) alert(info);
// 12, 13, 14, 15 ... 23, 24

[ Symbol.iterator ]를 따로 생성하여 fruit[Symbol.iterator]() 자체가 객체 fruit를 반환하도록 하였다.

무한개의 이터레이터를 만들기 위해서는 this.maxQuantity를 Infinity를 만들면 가능하다!

왜냐하면, next에 제약사항이 없고 next가 값을 계속 반환하는 것은 정상적인 동작으로 여겨지기 때문이다.
만약에 여기서 break를 사용하면 언제든지 반복을 멈출 수 있다!


✨ 문자열

배열과 문자열은 가장 광범위하게 쓰이는 내장 이터러블이다.
for ... of로 순회하면 각 글자를 순회하게 된다.

for(const char of "AvenJS"){
  console.log(char);
}

문자열을 구성하는 문자 각각에 대한 값을 차례대로 가져온다.

명시적인 이터레이터

for ... of를 사용하는 것 말고 앞서 사용했던 방법으로 문자열 이터레이터를 만들고, 수동으로 값을 가져와보자.

const avenJS = "AvenJS";
const iterator = avenJS[Symbol.iterator]();

let result = iterator;
while(!result.done){
  result = iterator.next();
  console.log(result.value);
}
  1. 문자열을 만든다.
  2. avenJS[Symbol.iterator]()로 iterator를 가져온다.
  3. iterator를 담을 result 변수를 선언한다.
  4. result.done === false이면 아직 next가 사용가능한 것이므로 이를 조건으로 하여 반복을 진행한다.

이터러블과 유사 배열

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

이터러블 객체라고 해서 유사 배열 객체는 아니고, 유사 배열 객체라고 해서 이터러블 객체인 것도 아니다.
또한, 이터러블 객체

const fruitsLikeArray = {
  0 : "apple",
  1 : "orange",
  length : 2
};

for(const fruit of fruitsLikeArray){ }

fruitsArray는 인덱스와 length를 가지고 있기 때문에 이터러블 객체가 아니라 유사 배열 객체이다. 때문에, Symbol.iterator가 없으므로 for ... of 문을 수행할 수 없다.

Array.from

이터러블과 유사 배열을 받아서 진짜 Array를 만들어주는 메서드가 Array.from 이다.

Array.from(obj[, mapFn, thisArg])
  • obj 바꾸고 싶은 객체
  • mapFn 새로운 배열에 obj의 요소를 추가하기 전에 각 요소를 대상으로 적용
  • thisArg 각 요소의 this
const fruitsLikeArray = {
  0 : "apple",
  1 : "orange",
  length : 2
};
const fruitsArray = Array.from(fruitsLikeArray);

fruitsArray에 배열이 형성되었고, 이는 for ... of 반복문을 수행하도록 동작하게 하였다.

👇mapFn을 사용해보자.

const quantityLikeArray = {
  0 : 1,
  1 : 12,
  2 : 24,
  length : 3
}
const quantityArray = Array.from(quantityLikeArray, quantity => quantity * 2);

mapFn으로 수량을 2배씩 변경시켜 배열을 만들었다.


📚 학습할 때, 참고한 자료 📚

profile
즐기면서 정확하게 나아가는 웹프론트엔드 개발자 https://happhee-dev.tistory.com/ 로 이전하였습니다

0개의 댓글