# 이터러블/이터레이터 프로토콜
@이터러블
-이터레이터를 리턴하는 [Symbol.iterator]() 를 가진 값
- 이터러블 프로토콜을 준수한 객체.
- 배열, 문자열, Map, Set은 이터러블 객체이다.
- 이터러블 객체는 for...of문 뿐만 아니라 스프레드 연산, 구조분해 할당이 가능하다.
Array 에 arr[Symbol.iterator] = null 넣으면 콘솔에 "Array는 Symbol.iterator가 아니다" 라고 나옴
@이터러블 프로토콜
- Well-know Symbol(JS가 기본 제공하는 빌트인 심볼 값)인 Symbol.iterator를 프로퍼티 키로 사용한 메소드를 직접 구현하거나 프로토타입 체인을 통해 상속받은 Symbol.iterator 메소드를 호출하면 이터레이터 프로토콜을 준수한 이터레이터를 반환한다.
- 이러한 규약을 이터러블 프로토콜이라고 하며, 이터러블 프로토콜을 준수한 객체를 이터러블이라 한다.
@이터레이터
- 이터레이터는 이터러블의 요소를 탐색하기 위한 포인터 역할.
- { value, done } 객체를 리턴하는 next() 를 가진 값
@이터레이터 프로토콜
- 이터러블의 Symbol.iterator 메소드를 호출하면 이터레이터 프로토콜을 준수한 이터레이터를 반환.
- 이터레이터는 next() 메소드를 소유하며, next() 메소드를 호출하면 이터러블을 순회한다. 순회를 하면서 value와 done 프로퍼티를 갖는 이터레이터를 객체로 반환한다.
- 이러한 규약을 이터레이터 프로토콜.
- 이터러블/이터레이터 프로토콜: 이터러블을 for...of, 전개 연산자 등과 함께 동작하도록한 규약 증가하는 i값
키벨류로 안넣어도 이터러블이터레이터 프로토콜때매 순환돈다
기존의 ES5에서 순회 방식
-ES5 까지는 기본적인 for, for...in, forEach 메소드 등 다양한 방법으로 순회가능했다.
<script>
const list = [1, 2, 3];
for (var i = 0; i < list.length; i++) {
log(list[i]);
}
const str = 'abc';
for (var i = 0; i < str.length; i++) {
log(str[i]);
}
</script>
선언적으로 달라진 ES6에서 순회방식
- ES6 에서부터는 for...of 문으로 array, set, map, 문자열을 간단하게 순회할 수 있다.
- 순회 가능한 자료구조를 이터러블로 통일하여 for...of, 스프레드 문법([...arr]), 구조 분해 할당의 대상으로 사용할 수 있도록 일원화했다.
## 기존과 달라진 ES6에서의 리스트 순회
- for i++
- for of
<script>
for (const a of list) {
console.log(a);
}
for (const a of str) {
console.log(a);
}
</script>
Array, Set ,Map 활용
- ES6에서 제공하는 Built-in-lterable 중 다음 세가지를 활용해 보았다.
### Array를 통해 알아보기
<script>
log('Arr -----------');
const arr = [1, 2, 3];
let iter1 = arr[Symbol.iterator]();
for (const a of iter1) log(a);
</script>
### Set을 통해 알아보기
<script>
log('Set -----------');
const set = new Set([1, 2, 3]);
for (const a of set) log(a);
</script>
### Map을 통해 알아보기
<script>
log('Map -----------');
const map = new Map([['a', 1], ['b', 2], ['c', 3]]);
for (const a of map.keys()) log(a);
for (const a of map.values()) log(a);
for (const a of map.entries()) log(a);
console.clear();
</script>
사용자 정의 이터러블을 활용
<script>
const iterable = {
[Symbol.iterator]() {
let i = 3;
return {
next() {
return i == 0 ? {done: true} : {value: i--, done: false};
},
[Symbol.iterator]() {
return this;
}
}
}
};
let iterator = iterable[Symbol.iterator]();
iterator.next();
iterator.next();
// log(iterator.next());
// log(iterator.next());
// log(iterator.next());
for (const a of iterator) log(a);
// const arr2 = [1, 2, 3];
// let iter2 = arr2[Symbol.iterator]();
// iter2.next();
// log(iter2[Symbol.iterator]() == iter2);
// for (const a of iter2) log(a);
for (const a of document.querySelectorAll('*')) log(a);
const all = document.querySelectorAll('*');
let iter3 = all[Symbol.iterator]();
log(iter3.next());
log(iter3.next());
log(iter3.next());
</script>
전개 연산자를 활용
<script>
console.clear();
const a = [1, 2];
// a[Symbol.iterator] = null;
log([...a, ...arr, ...set, ...map.keys()]);
</script>
'Programming Language > Javascript' 카테고리의 다른 글
[Javascript] split() 지정 구분기호로 문자열을 배열로 분할 (0) | 2023.03.30 |
---|---|
[Javascript] "some()" 배열의 객체에 원하는 값이 있으면 True 반환 (0) | 2023.03.25 |
[Javascript] find(), filter() 두 배열에서 일치하는값 찾기 (2) | 2023.03.05 |
[Javascript] 객체(object) 속성이나 문자열의 개수 구하는법 (0) | 2023.02.25 |
[Javascript] Array map() 함수, 배열에 특정값만 추출해 새로운 배열 만들기 (0) | 2023.02.16 |