Iterable Object 에 대해 정리해본다.
Iterable이란 "반복가능"이라는 사전적인 뜻을 갖고있다.
즉 Iterable Object는 "반복 가능한 객체"는 의미다.
"순회가 가능한 객체형태의 데이터"라고 이해해도 좋을 것 같다.
JS에서는 줄여서 Iterable 이라고도 부른다.
JS에서 순회가 가능하다는 의미는
[...]
) 을 사용할 수 있음을 의미한다.
기본적으로 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.
위에서 Object
, Number
타입이 Iterable 하지 않다는걸 알았다.
그러나 Iterable 하게 만들어 줄 수 있다.
Iterable Object의 공통점은 Symbol.Iterator
라는 메소드를 가지고 있다는 점이다.
Array
, String
타입은 기본적으로 Symbol.Iterator
메소드가 내장되어있지만, Object
, Number
는 가지고있지 않다.
다시말해, Object, Number에 Symbol.iterator
를 정의해준다면 iterable Object가 된다.
Symbol.Iterator
란Iterator
를 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]
유사배열과 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