이터레이터

lee jae hwan·2022년 8월 6일

javascript

목록 보기
90/107

이터레이터란 객체프로퍼티 반복순회시 사용되는 객체다.

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);

제너레이터 콤포지션

0개의 댓글