자바스크립트 빌트인 이터러블이 아닌 사용자가 특정 데이터 구조를 순회가능하도록 만들기 위해서 사용자 정의 이터러블을 만들수 있습니다.
const iterable = {
[Symbol.iterator]() {
return {
next() {
return {value, done}
}
}
}
}
//실제 예시
const iterable = {
[Symbol.iterator](){
let i = 3;
return{
next () {
return i==0 ? {done:true}:{value: i--, done:false}
}
}
}
}
let iterator = iterable[[Symbol.iterator]]();
log(iterator.next());
그런데!! 위의 소스는 Well-formed iterator 가 아닙니다. ❌❌
"Well-formed iterator"는 이터레이터(iterator) 객체가 일반적으로 기대되는 동작을 제대로 수행하는 것을 말합니다. 이터레이터는 이터레이터 프로토콜(iterator protocol)을 준수해야 하며, 적절한 next()
메서드를 가지고 있어야 합니다.
Well-formed iterator는 다음과 같은 특징을 가지고 있습니다:
next()
메서드: 이터레이터 객체는 next()
메서드를 가지고 있어야 합니다. next()
메서드는 { value, done }
형태의 객체를 반환해야 합니다. value
는 현재 값을 나타내며, done
은 순회가 완료되었는지 여부를 나타냅니다.
반복 가능성: 이터레이터 객체는 자체적으로 이터러블(iterable)해야 합니다. 이는 이터레이터 객체의 [Symbol.iterator]()
메서드가 이터레이터 🌟자신을 반환🌟해야 함을 의미합니다. 이는 이터레이터 객체를 다시 이터레이션할 수 있는 순환 가능한 객체로 만들어줍니다.
순회 동작: 이터레이터 객체는 순회를 위한 반복 구문인 for...of
루프와 함께 사용될 수 있어야 합니다. 이는 이터레이터 객체가 이터러블 프로토콜을 준수하고 순차적으로 값을 반환할 수 있어야 함을 의미합니다.
const iterable = {
[Symbol.iterator](){
let i = 3;
return{
next () {
return i==0 ? {done:true}:{value: i--, done:false}
},
[Symbol.iterator]() { return this; }
}
}
}
아래의 두 코드는 모두 매개변수만큼 for문을 돌릴수 있도록 구현한 사용자 정의 iterator입니다.
첫 번째 코드에서 Symbol.iterator 메서드는 새로운 객체를 생성하여 해당 객체의 next() 메서드를 반환합니다. 이 방법은 명시적으로 이터레이터 객체를 생성하여 반환하는 방식입니다.
두 번째 코드에서 Symbol.iterator 메서드는 this를 반환합니다. 이렇게 하면 현재 객체가 이터레이터 역할을 수행하게 됩니다. 이 방법은 객체 자체를 이터레이터로 사용할 때 편리한 방식입니다.
function createCustomIterator(maxValue) {
let currentValue = 1;
return {
[Symbol.iterator]() {
return {
next() {
if (currentValue <= maxValue) {
return { value: currentValue++, done: false };
} else {
return { done: true };
}
},
[Symbol.iterator]() {
return this;
}
};
}
};
}
function createCustomIterator(maxValue) {
let currentValue = 1;
return {
[Symbol.iterator]() {
return this;
},
next() {
if (currentValue <= maxValue) {
return { value: currentValue++, done: false };
} else {
return { done: true };
}
}
};
}