이터레이터란 객체프로퍼티 반복순회시 사용되는 객체다.
let range = {
[Symbol.iterator](){
return {
nex(){
return {done:false,value:xxx}
}
};
}
};
range객체는 Symbol.iterator메소드를 가지고 있다.
Symbol.iterator는 for of 구문시 호출되며 반환되는 이터레이터객체가 반복될때마다 next메소드가 호출되어 값과 반복종료를 나타낸다.
let range = {
from:1,
to:5,
[Symbol.iterator](){
return {
cur:this.from,
end:this.to,
next(){
if(this.cur <= this.end){
return {done:false,value:this.cur++};
}else{
return {done:true};
}
}
};
}
};
for (const val of range) {
console.log(val);
}
range객체는 이터러블객체라고 한다.
이터러블하지 않은 객체를 이터러블하게 하려면 Symbol.iterator메소드를 구현하면 된다.
iterator메소드를 구현하는 것이 어렵지는 않지만 다소 불편할 수 있어 보다 간편하게 구현하는 방법을 제공한다.
generator함수
generator함수는 일반적인 함수와달리 generator객체를 생성하기위한 생성자함수다.
let range = {
from: 1,
to: 5,
*[Symbol.iterator]() {
for (let index = this.from; index <= this.to; index++) {
yield index;
}
},
};
yield문법을 사용하여 반복순회를 조정이 할 수 있다.
function* generateSequence() {
yield 1;
yield 2;
return 3;
}
let genObj = generateSequence();
console.log(genObj);
제너레이터함수를 호출하면 제너레이터함수가 진행되지 않고 제너레이터객체가 생성되어 반환된다.
(Symbol.iterator메소드를 호출하면 이터레이터객체가 반환되는 것과 같다)
반복순회구문으로 이터레이터 next메소드가 내부적으로 호출되었으나 제너레이터 next메소드는 사용자가 호출할 수도 있다.
function* generateSequence() {
yield 1;
yield 2;
return 3;
}
let genObj = generateSequence();
let one = genObj.next();
console.log(one); // 1
next메소드가 호출되면 제너레이터함수가 진행되고 첫번째 yield구문에서 {done:false, value:1}객체를 반환하고 다음줄에서 멈추어있다.
next메소드가 호출되면 yield 2;로 {done:false, value:2}객체를 반환하고 다음줄에서 멈추게 된다.
next메소드가 호출되면 return문으로 {value: 3, done: true}객체를 반환하고 종료된다.
function* generateSequence() {
yield 1;
yield 2;
return 3;
}
let genObj = generateSequence();
for (const val of genObj) {
console.log(val); // 1, 2
}
{done:true} done프로퍼티가 true면 for구문은 반복을 벗어나기때문에 3값은 출력되지 않는다.
function* generateSequence() {
yield 1;
yield 2;
yield 3;
}
let genObj = [0,...generateSequence()];
제너레이터객체는 이터러블객체이므로 나머지연산자사용이 가능하다.
function* generateSequence(start, end) {
for (let i = start; i <= end; i++) yield i;
}
function* fn(){
yield* generateSequence(48, 57);
yield* generateSequence(65, 90);
yield* generateSequence(97, 122);
}
let str='';
for(const val of fn() ){
str+=String.fromCharCode(val);
}
console.log(str);
제너레이터 콤포지션