티스토리 뷰

for of를 적용할 수 있는 객체를 이터러블(Iterable)이라고 부른다.

for of 를 적용할 수 있으려면(= 이터러블이려면)

  • 해당 객체는 Symbol.iterator 이라는 메서드를 갖고 있어야 한다.
  • for of를 사용하려면 Symbol.iterator 메서드를 호출한다.
  • 위 메서드는 iterator 를 리턴해야 한다. 이터레이터는 next 메서드를 갖고 있는 객체다.
  • next 메서드를 호출하면 {done: Boolean, value: any} 이런 모양을 가진 객체를 리턴해야 한다. done 프로퍼티 값이 true면 이터레이션이 끝난 것이고, 아니라면 value가 다음 value가 된다.
let range = {
  from: 1,
  to: 5
};

range[Symbol.iterator] = function() {
  return {
    current: this.from,
    last: this.to,
    next() {
      if (this.current <= this.last) {
        return { done: false, value: this.current++ };
      } else {
        return { done: true };
      }
    } 
  }
}

for (let num of range) {
  alert(num); // 1, 2, 3, 4, 5
}

이렇게 이터레이터를 따로 만들어서 이터레이터에게 순회를 시키는 것은 관심사의 분리다. 이터레이터를 따로 만들지 않고, 객체 자체를 이터레이터로 만들 수 있지만 그렇게 되면 이 객체를 동시에 이터레이션 할 수는 없게 된다. 유일한 이터레이터가 객체 자체이기 때문이다. 하지만 동시에 이터레이션하는 일이 아주 드문 일이긴 하다.

Array-like 과 Iterable 의 차이

  • Array like은 인덱스가 있고 길이(length)가 있는 객체다.
  • let arrayLike = { 0: "Hello", 1: "World", length: 2 }; // 이 객체는 numeric 인덱스와 length 프로퍼티가 있으니 array like이지만 이터러블은 아니다.
  • 이터러블은 위에서 말한 것처럼 Symbol.iterator 메서드를 이식하고 있는 객체다.
  • 둘의 관계는 배타적이지 않으며 array-like이면서 동시에 이터러블일 수 있다. 예를 들어 string은 이터러블이면서 array-like이다.
  • 기본적으로 Object 는 이터러블이 아니다. 그래서 직접적으로 for of를 사용할 수 없고, for of를 사용하려면 위에서 한 것처럼 직접 이터레이션 프로토콜을 이식해서 이터러블로 만들거나, Object.keys, Object.values, Object.entries 처럼 이터러블로 만들어주는 메서드를 사용해야 한다. (덧. 참고로 Map은 이터러블이다. )
  • array-like이라고 해서 진짜 Array랑 같은 것은 아니다. 위의 arrayLike 변수를 보면 알겠지만, 해당 객체는 push나 pop같은 메서드를 갖고 있는 진짜 Array는 아니다.

Array.from

  • Array.from이터러블 또는 array-like을 인자로 받아서 진짜 Array로 바꿔주는 스태틱 메서드다.
  • Array.from(arrayLike or iterable[, mapFn[, thisArg]])
  • 두 번째 인자인 MapFn 은 배열의 모든 원소에 대해 호출될 매핑 함수다.

Ref

https://javascript.info/iterable

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함