Iterator/Iterable Protocol
Iterator: { value, done} 객체를 return 하는 next()를 가진 객체
Iterable: Iterator를 return하는 [Symbol.iterator]()를 가진 객체
// 배열이나 string, Map, Set 등이 Iterable 객체에 해당한다.
Iterator/Iterable Protocol: [for...of], [Spread Operator] 등 이터러블이나 이터레이터 프로토콜을 따르는 연산자함게 동작하도록 하는 규약
// Iterable
const u_iterable = {
[Symbol.iterator]() {
let i = 3;
return {
next() {
return i === 0 ? { value: undefined, done: true} : {value: i--, done: false}
}
}
}
}
// Iterator
const u_iterator = u_iterable[Symbol.iterator]();
for(const it of u_iterable) console.log(it) // 3, 2, 1
for(const it of u_iterator) console.log(it) // Uncaught TypeError: u_iterator is not iterable
u_iterator 변수에 u_iterable[Symbol.iterator]()를 할당했는데 왜 u_iterator 변수가 iterable이 아니라는 에러가 뜰까?
Iterable의 정의를 다시 한번 보면 Iterator를 return하는 [Symbol.iterator]()를 가진 객체가 Iterable이라고 쓰여있다 하지만 콘솔을 찍어보면 아래와 같이 u_iterator에는 next() 만 존재하기 때문에 iterable이 아니라는 에러가 뜨는것이다.
그럼 u_iterator를 iterable로 만드는 방법은 간단하게 [Symbol.iterator]()를 사용했을 때 자기 자신을 return 해주기만 하면 된다. 이를 well-formed iterator라고 하며, iterator 객체는 iterable 해야하고 자기 자신을 return해야 한다. 즉 u_iterator[Symbol.iterator]() === u_iterator 해야 한다.
// Iterable
const u_iterable = {
[Symbol.iterator]() {
let i = 3;
return {
next() {
return i === 0 ? { value: undefined, done: true} : {value: i--, done: false}
},
[Symbol.iterator]() { return this; }
}
}
}
// Iterator
const u_iterator = u_iterable[Symbol.iterator]();
for(const it of u_iterable) console.log(it); // 3, 2, 1
for(const it of u_iterator) console.log(it); // 3, 2, 1
console.log(u_iterator[Symbol.iterator]() === u_iterator); // true
'NodeJS > FuncP' 카테고리의 다른 글
Go, Pipe, Curry (1) | 2024.02.20 |
---|---|
함수형 프로그래밍이란? (2) | 2024.02.19 |