Iterable Object

이짜젠·2021년 10월 30일
0

Iterable Object 에 대해 정리해본다.
Iterable이란 "반복가능"이라는 사전적인 뜻을 갖고있다.

즉 Iterable Object는 "반복 가능한 객체"는 의미다.
"순회가 가능한 객체형태의 데이터"라고 이해해도 좋을 것 같다.
JS에서는 줄여서 Iterable 이라고도 부른다.


Iterable Object

JS에서 순회가 가능하다는 의미는

  • for...of 문법
  • Spread 문법([...])

을 사용할 수 있음을 의미한다.

기본적으로 Array, String와 같은 자료형은 Iterable하다.

const arr = [ 'a', 'b', 'c' ];
for (let item of arr) { console.log(item) } // a\n b\n \nc 
console.log([...arr]); // ["a", "b", "c"]


const str = 'def';
for (let char of str) { console.log(char) } // d\n e\n f\n
console.log([...str]); // ["d", "e", "f"]

Object, Number와 같은 자료형은 Iterable 하지 않다.

const obj = {
  start: 1,
  end: 5,
}
for (let prop of obj) {
  console.log(prop)
}
// TypeError: Invalid attempt to iterate non-iterable instance.

Symbol.Iterator

위에서 Object, Number 타입이 Iterable 하지 않다는걸 알았다.
그러나 Iterable 하게 만들어 줄 수 있다.

Iterable Object의 공통점은 Symbol.Iterator 라는 메소드를 가지고 있다는 점이다.

Array, String 타입은 기본적으로 Symbol.Iterator 메소드가 내장되어있지만, Object, Number는 가지고있지 않다.
다시말해, Object, Number에 Symbol.iterator 를 정의해준다면 iterable Object가 된다.

Symbol.IteratorIterator를 return하는 함수다.

Iterator는 데이터 순회에 사용될 로직이라고 생각하면된다.
Iterator는 객체형태로써 다음의 구조를 따른다.

type Iterator = {
  current: any,
  last: any,
  next: () => { 
    done: boolean, // 순회의 종료여부 값
    value: any // 현재 순회 사이클에서 사용하게될 값
  }
}

일반 객체에 Symbol.iterator 메소드를 정의해줌으로써 Iterable하게 만들어보자.

const obj = {
  start: 1,
  end: 5,
  [Symbol.iterator]: function () {
    return {
      current: this.start,
      last: this.end,
      next() {
        if (this.current > this.last) {
          return {
            done: true
          };
        } else {
          return {
            value: this.current++,
            done: false
          };
        }
      }
    };
  }
};

console.log([...obj]); // [1, 2, 3, 4, 5]

유사배열

length와 index를 가지고 있는 객체 데이터

배열과 유사한 형태의 객체를 말한다.
Iterable과는 별개다.

length, index 를 갖고 있고, Symbol.iterator를 메소드로 갖고있다면 Iterable유사배열이라고 볼 수 있다.

var data = {
	0: 'a',
	1: 'b',
	2: 'c',
	length: 2 // index 0부터 length의 값 만큼만 읽어온다.
};
console.log(Array.from(data)) // ['a', 'b']

var data2 = {
	1: 'b',
	2: 'c',
	length: 2
};
console.log(Array.from(data2)) // [undefined, 'b']

var data3 = {
	1: 'b',
	2: 'c',
	length: 4
};
console.log(Array.from(data3)) // [undefined, 'b', 'c', undefined]

Array.from

유사배열과 Iterable Object는 Array가 아닌 객체데이터다.
따라서 Array 의 메소드들을 사용할 수 없다.

Array.from은 유사배열이나 Iterable Obejct를 Array 타입으로 변환해준다.

Array.from 으로 변환된 이후에는 Array로 취급되며, Array 메소드들을 사용할 수 있다.

const str = "def";
console.log(str.map((char, idx) => `${idx}: ${char}`)) // TypeError: str.map is not a function

const strArr = Array.from(str)
console.log(strArr.map((char, idx) => `${idx}: ${char}`)) //  ["Array.from: d", "Array.from: e", "Array.from: f"]

참고

https://poiemaweb.com/es6-iteration-for-of
https://ko.javascript.info/iterable

profile
오늘 먹은 음식도 기억이 안납니다. 그래서 모든걸 기록합니다.

0개의 댓글