사용자 정의 이터러블을 구현하며 이터러블에 대해 정확하게 알아봅니다.
/**
* 사용자 이터러블 정의
*/
const iterable = {
[Symbol.iterator]() {
let i = 1;
return {
next() {
return i > 3 ? {done: true} : {value: i++, done: false};
}
};
}
};
let iterator = iterable[Symbol.iterator]();
// console.log(iterator.next());
for (const a of iterable) {
console.log(a);
}
위와 같은 사용자가 직접 정의한 이터러블을 본다면, iterable에 [Symbol.iterator]()가 구현되어있으므로, for ... of 문법을 통하여 리스트 반복이 가능합니다.
실제 실행시 기본 내장 객체인 array, map, set과 마찬가지로 next() 함수가 리턴되며 반환됩니다. for ... of문 내부적으로는 iterator.next()를 실행하면서 클로저인 next 가 i를 하나씩 증가시키며 a에 i값을 하나씩 담게 되면서 모든값을 반복하여 출력 하게 됩니다.
이전 포스트인 이터러블/이터레이터에서 말씀 드렸던 것처럼, 이터러블은 [Symbol.iterator]() 값 자체에도 본인을 리턴하는 [Symbol.iterator]() 가 있으며, iterator.next(); 와 같이 일부분을 선행하여 진행하였을 경우, 그 이후의 값을 부터 반복이 이루어질 수가 있습니다.
하지만 위의 사용자 정의 iterable 의 경우 자신의 [Symbole.iterator]() 값을 가지고 있는 iterator 는 for ... of 문으로 반복할 수 없으며, iterator.next()를 선행한 후에도 처음 값부터 for ... of 문으로 반복이 이루어 집니다.
내장 객체와 동일한 이터러블/이터레이터 프로토콜을 지원하기 위해서 자신의 자신의 [Symbole.iterator]()에서 자기 자신을 리턴하는 자신의 [Symbole.iterator]()를 만들어 줍니다.
/**
* 사용자 이터러블 정의
*/
const iterable = {
[Symbol.iterator]() {
let i = 1;
return {
next() {
return i > 3 ? {done: true} : {value: i++, done: false};
},
[Symbol.iterator]() {
return this;
}
};
}
};
let iterator = iterable[Symbol.iterator]();
iterator.next();
for (const a of iterable) {
console.log(a);
}
// > 2
// > 3
위와 같이 [Symbole.iterator]()값에 자기자신을 리턴하는 [Symbole.iterator]() 객체를 만들어준다면, [Symbole.iterator]() 자체로도 for ... of 문으로 반복이 가능하며, iterator.next(); 로 선행 후에는 다음값부터 for ... of 문으로 반복이 됩니다.
이처럼 이터러블/이터레이터 프로토콜은 ES6에서 지원하는 내장 값만 해당 프로토콜을 지원하는것이 아니라, 오픈 소스 또는 브라우저의 dom과 같은 값들이 반복 및 순회가 가능한 형태의 값을 가진 값들은 대부분 이터러블/이터레이터 프로토콜을 따라 구현이 되고 있습니다.
아래 예제를 통해 관련 코드 확인이 가능합니다.
Example
/**
* dom NodeList 이터러블 정의
*/
const list = document.querySelectorAll('*');
for (const a of list) {
console.log(a);
}
const queryAllIterator = list[Symbol.iterator]();
queryAllIterator.next();
queryAllIterator.next();
for (const a of queryAllIterator) {
console.log(a);
위와 같이 document.querySelectorAll 도 for ... of 문으로 반복순회가 가능하며, 이는 해당 객체가 배열이라서가 아닌 [Symbol.iterator]() 가 구현이 되어 있기 때문에 반복 순회가 가능한 것입니다. 이터러블/이터레이터 프로토콜 특성에 따라 next() 를 이용한 우선 순회 및 자기자신에 대한 [Symbole.iterator]() 리턴 특성 또한 모두 포함하고 있습니다.
'JAVASCRIPT > 함수형 자바스크립트' 카테고리의 다른 글
함수형 자바스크립트 - for ... of, 전개 연산자, 구조분해, 나머지 연산자 (0) | 2022.11.17 |
---|---|
함수형 자바스크립트 - 제너레이터 (0) | 2022.11.16 |
함수형 자바스크립트 - 이터러블/이터레이터 (0) | 2022.11.14 |
함수형 자바스크립트 - 리스트 반복 (0) | 2022.11.14 |
함수형 자바스크립트 특징 - 고차 함수 (0) | 2022.11.11 |