-
Section 10. 자바스크립트 이터러블자바스크립트 2023. 4. 7. 12:01
I. 이터러블 프로토콜 iterable protocol
- 반복, 순회 기능을 사용하는 주체간의 통일된 규격이다.
- 공통 기능들 : for ... of, 스프레드 문법, 배열 디스트럭쳐링
이터러블 iterable - 이터러블 프로토콜을 준수하는 객체
- 배열, 문자열, Set, Map, arguments 등 ...
- 키 Symbol.iterator (well-known 심볼)의 값으로 이터레이터를 반환하는 메서드를 가진다.
*Symbol.iterator같이 잘 알려져서 많은 것들의 식별자로 사용되는 것을 well-known 심볼이라 한다.
배열 하나를 출력해보자.
[]
그리고 콘솔에서 그걸 펼쳐보면 다음과 같다.
프로토타입 밑에 Symbol.iterator를 키로하는 어떤 함수가 들어있는 것을 볼 수 있다.
이 프로퍼티가 이터레이터의 핵심이다.
console.log( [][Symbol.iterator], ''[Symbol.iterator], new Set()[Symbol.iterator], new Map()[Symbol.iterator] );
배열, 문자열, Set, Map에 대한 Sysmbol.iterator의 값을 출력해봤다. 출력문은 다음과 같다.
공통적으로 어떤 함수들이 출력 되는 것을 볼 수 있다.
이런 함수들은 이터러블이 아닌 함수에는 존재하지 않는다.
// 다른 타입의 인스턴스에는 없음 console.log( (1)[Symbol.iterator], (true)[Symbol.iterator], { x: 1 }[Symbol.iterator] ); //undefined undefined undefined
이 함수들을 실행 괄호 ()를 붙여서 실행해보면
console.log( [][Symbol.iterator](), //Array Iterator {} ''[Symbol.iterator](), //StringIterator {} new Set()[Symbol.iterator](), //SetIterator {} new Map()[Symbol.iterator]() //MapIterator {} );
각각 해당하는 자료형의 이터레이터를 반환하는 것을 알 수 있다.
II. 이터레이터 iterator
next 메서드를 통해 이터러블을 순회하며 값을 반환한다.
const arr = [1, 'A', true, null, {x: 1, y: 2 }]; const arrIterator = arr[Symbol.iterator](); console.log(arrIterator);
arr의 심볼 이터레이터에 접근해서 arrIterator를 뽑아냈다.
그리고 그것을 출력해보면 next()라는 함수를 가지고 있는 것을 볼 수 있다.
arr[Symbol.iterator]()를 통해서 반환된 Array Iterator 객체는 next라는 함수(기능)를 가지고 있는 것이다.
이 기능을 이용하면 arr의 요소들을 차례대로 뽑아낼 수 있다.
arrIterator.next(); //{value: 1, done: false} arrIterator.next(); //{value: 'A', done: false} arrIterator.next(); //{value: true, done: false} arrIterator.next(); //{value: null, done: false} arrIterator.next(); //{value: {…}, done: false} arrIterator.next(); //{value: undefined, done: true}
이터레이터 프로토콜 iterator protocol
next 메서드의 반환 객체 내 요소는 다음과 같다
- value - 해당 차례에 반환할 값
- done - 순회 종료 여부 (마지막 값 반환 다음 차례부터)
III. 이터러블 만들어보기
주사위를 열 번 굴리는 이터러블
const diceTenTimes = { // ⭐️ 아래의 메서드를 갖는 것이 이터러블 프로토콜 [Symbol.iterator] () { let count = 0; let maxCount = 10; // ⭐️ 이터레이터(next 메서드를 가진 객체)을 반환 return { next () { return { value: Math.ceil(Math.random() * 6), done: count++ >= maxCount } } } } }
diceTenTimes라는 객체를 하나 만들었다.
이 객체에 Symbol.iterator를 키로 하려면 [ ]를 써줘야 한다. 거기에 실행 괄호가 붙어서 심볼 이터레이터라는 메서드가 실행 된다.
이 메서드는 이터레이터 객체를 반환한다. 그 객체에는 next라는 함수가 있고 그 함수가 반환하는 것은
value: Math.ceil(Math.random() * 6),
done: count++ >= maxCount
이것이 되는 것이다.
실행을 해보면 다음과 같다
const diceIterator = diceTenTimes[Symbol.iterator](); for (let i = 0; i < 12; i++) { console.log( diceIterator.next() ); }
여기서 next의 done 프로퍼티가 true를 반환 했는데도 계속 출력된 이유는 for문의 종료 조건때문이다.
for ... of 문도 사용이 가능하다.
// 💡 for ... of 문 사용 가능 for (const num of diceTenTimes) { console.log(num); }
for 문과는 다르게 딱 10번 출력된 것을 볼 수 있다.
스프레드 문법도 사용 가능하다.
const diceResults = [...diceTenTimes]; console.log(diceResults); //[5, 1, 5, 4, 3, 3, 4, 1, 1, 2]
*이 예시는 제너레이터로 보다 간편하게 구현이 가능하다.
'자바스크립트' 카테고리의 다른 글
Section 11. 자바스크립트 에러 핸들링 (0) 2023.04.07 Section 10. 자바스크립트 제너레이터 (0) 2023.04.07 Section 10. 자바스크립트 Map (0) 2023.04.06 Section 10. 자바스크립트 Set (0) 2023.04.06 Section 9. 자바스크립트 Symbol (0) 2023.04.06