티스토리 뷰

5.6 Iterables

Symbol.iterator (잘 이해가 안됨...)

배열은 아니지만 셀 수 있는 객체가 있다. 해당 객체를 셀 수 있도록 하려면 Symbol.iterator가 필요하다.

또한, 내부적으로 next 함수를 정의해야 하는데, 해당 함수는 {done: Boolean, value: any} 형태의 객체를 반환해야 한다.

let range = {
  from: 1,
  to: 5
};

// 1. call to for..of initially calls this
range[Symbol.iterator] = function() {

  // ...it returns the iterator object:
  // 2. Onward, for..of works only with the iterator object below, asking it for next values
  return {
    current: this.from,
    last: this.to,

    // 3. next() is called on each iteration by the for..of loop
    next() {
      // 4. it should return the value as an object {done:.., value :...}
      if (this.current <= this.last) {
        return { done: false, value: this.current++ };
      } else {
        return { done: true };
      }
    }
  };
};

// now it works!
for (let num of range) {
  alert(num); // 1, then 2, 3, 4, 5
}

done이 true인 경우 더 이상 반복하지 않는다.

Iterables and array-likes

Iterables와 array-likes는 비슷해 보이지만 엄연히 다르다. Iterables는 Symbol.iterator 메서드를 구현한 객체이고, Array-likes는 인덱스와 length를 가진 객체다. 그래서 array처럼 보인다. 둘 다의 특징을 가진 객체도 있다. string의 경우 Iterable과 array-like의 특징을 다 가지고 있다.

let arrayLike = { // has indexes and length => array-like
  0: "Hello",
  1: "World",
  length: 2
};

// Error (no Symbol.iterator)
for (let item of arrayLike) {}

위는 array-like이다. 인덱스와 length 속성이 존재하기 때문이다.

 

length가 존재하고 인덱스 속성을 가진 객체를 유사 배열이라 한다. 대부분의 배열 내장 메서드는 실제 배열 그 자체보다 iterable 한 객체들에 초점이 맞춰져 있어서 유사배열 객체들에도 잘 동작한다. 

Array.from

Array.from 은 iterable이나 array-like 값을 가지고 진짜 배열로 변환한다.

let arrayLike = {
  0: "Hello",
  1: "World",
  length: 2
};

let arr = Array.from(arrayLike); // (*)
alert(arr.pop()); // World (method works)

문자열도 가능하다. 

let str = '𝒳😂';

// splits str into array of characters
let chars = Array.from(str);

alert(chars[0]); // 𝒳
alert(chars[1]); // 😂
alert(chars.length); // 2
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday