오늘은 iterable(이터러블), iterator(이터레이터)에 대한 이야기를 한번 해볼건데, 배열이나, Map과 같은 순회가능한 객체들을 다룬다면 이 개념에 대한 이해를 가지고 있는 편이 좋다. 대부분 학원에서는 for / while문을 사용하면 요소하나하나 꺼내쓸 수 있다. 이렇게만 가르쳐주게 되는데, 이게 그냥 초반 입문 시기나 개발을 취미로 하는 입장에서는 전혀 문제될게 없으나 좀 더 전문적인 영역으로 진출하고자 하는 인재들에게는 이 개념의 존재를 알고 있는게 차후 Object에서 Custom Iterator를 적용한다던가 같은 응용이 가능하기 때문에 기왕이면 학습해두길 권하고 싶다.
1. Iterable Protocol & Iterator Protocol
왜 또 Protocol같은 거슬리는 워딩을 붙여놓냐 라고 하는 사람이 있을텐데, 이 프로토콜은 뭐 되게 광범위하게 전세계적으로 약속한 규칙 이런거도 아니고 ES6가 나오면서 적용된 문법적 규칙 같은거라, 막 대단한 의미를 지니고 있지 않으니 그냥 가볍게 들여다봐주면 좋겠다.
iterable은 이 iterable Protocol을 준수한 순회가능한 객체다. 이런 정의가 있는데, 따지고 보면 그냥 Symbol.iterator 메소드를 구현해놨거나, 아니면 자연스럽게 프로토타입 체인을 통해 상속한 케이스가 Iterable Protocol을 준수한거다. Symbol이 뭔데요? 라고 할텐데, 저건 Symbol얘기로 한 편 더 쓰겠다.
그럼 iterator Protocol은 뭐냐, next() 메서드를 가지고 있고, 이를 통해서 요소들을 순회하면서, 그 결과 값으로
{
value: 1,
done: false
}
요러게 생긴 result 객체를 리턴해야만 한다는 규칙임.
이런 규칙을 정하게 된 배경을 한번 얘기해보자면, 데이터가 복수로 담겨있는 자료들은 Array, Map 등등 여러가지가 있는데, 그 자료들이 이런 규칙없이 자기만의 고유한 순회체계를 갖는다면 각자 for문에 해당하는 문법 만들어줘야해서 개발자도 골머리 썩었을거고, 사용자들도 공부하기 힘들었을거다. 그래서 순회 가능한 객체가 되기 위한 특정 규칙을 정해둠으로써 몇가지 정해진 문법만으로도 모든 자료형태를 순회할 수 있도록 하고, 공부하는데에도 관련 내용에 대한 분량을 줄일 수가 있는 것이다.
2. Iterable / Iterator
위에서 언급한 Iterable Protocol을 준수한 객체는 Iterable이라고 불릴 수 있으며, 이 객체들은 모두 for~of 문 / spread 문법 등을 사용할 수가 있다.
Iterator의 경우엔 iterable과 동일하게 iterator Protocol을 준수한 것이고, iterable 객체의 요소를 탐색하기 위한 포인터라고 정의되어있다.
말이 복잡한데, iterable은 이제 드디어 순회 가능한 객체다!라고 이야기 할 수 있다. 정도로 쉽게 말할 수 있을 것 같고, iterator의 경우엔 순회 가능한 객체의 요소들을 꺼낼 수 있는 메서드 정도로 생각하면 될 것 같다.
아까 위에서 말했다시피 result 객체를 리턴하는 규칙이 있다고 했는데, 이 result 객체 내에 존재하는 done Property를 통해서 for~of 문이 동작한다고 생각하면 된다. done Property가 true 값을 가질 때 순회를 종료하는 방식이다.
3. 직접 Iterable 객체를 만들기
const fibonacci = {
// Symbol.iterator 메소드를 구현하여 이터러블 프로토콜을 준수
[Symbol.iterator]() {
let [pre, cur] = [0, 1];
// 최대값
const max = 10;
// Symbol.iterator 메소드는 next 메소드를 소유한 이터레이터를 반환해야 한다.
// next 메소드는 이터레이터 리절트 객체를 반환
return {
// fibonacci 객체를 순회할 때마다 next 메소드가 호출된다.
next() {
[pre, cur] = [cur, pre + cur];
return {
value: cur,
done: cur >= max
};
}
};
}
};
// 이터러블의 최대값을 외부에서 전달할 수 없다.
for (const num of fibonacci) {
// for...of 내부에서 break는 가능하다.
// if (num >= 10) break;
console.log(num); // 1 2 3 5 8
}
출처 : https://poiemaweb.com/es6-iteration-for-of
원래 기본적인 객체의 경우 iterable이 아니다. 하지만 [Symbol.iterator] 메서드를 추가하면서 iterable한 객체로 커스텀이 가능한데, 위의 코드에서 볼 수 있듯, iterable Protocol, iterator Protocol을 준수하며 작성하면 for~of 문 사용이 가능해진다.
'Dev > JavaScript' 카테고리의 다른 글
[JavaScript] BigInt (0) | 2023.07.25 |
---|---|
[JavaScript] Symbol (0) | 2023.07.17 |
[JavaScript] Wrapper Object (0) | 2023.07.13 |
[JavaScript] ProtoType (2) (0) | 2023.07.13 |
[JavaScript] ProtoType (1) (0) | 2023.07.05 |