JS의 반복자 및 생성기

문제를 풀면서 JavaScript의 Iterator와 Generator에 대해 배웠습니다. 따라서 여기에서 이러한 개념에 대해 논의하고 내가 만난 것과 동일한 문제를 사용하여 개념을 이해하려고 노력할 것입니다.

문제를 살펴보고 해결 방법을 이해하기 전에 몇 가지 이론부터 시작하겠습니다...

반복자



반복자는 for...of 루프를 사용하여 반복할 수 있는 객체입니다.

모든 iterable은 Symbol.iterator 메서드를 포함하는 객체를 반환하며, 이를 반복하려고 하거나 iterable(for...of 루프 사용)처럼 동작하기를 원하면 Symbol.iterator 메서드가 호출되어 다음을 반환합니다. 객체(반복자). 반환된 객체에는 next 메서드가 포함되며, 이 메서드는 다른 값이 반복되는지 여부에 관계없이 반복의 값과 상태(부울 사용)로 객체를 생성합니다.

다른 메서드( Symbol.iterator )가 있는 객체(반복자)를 반환하는 메서드( next ) 🤔 - 복잡하죠?

이제 반복자를 사용하여 문제를 해결하여 위의 문장을 더 잘 이해해 봅시다.

문제:

Q. Can you create a range(from, to) that makes the following work?

for (let num of range(1, 4)) {
  console.log(num)  
}
// 1
// 2
// 3
// 4

This is a simple one, could you think of more fancy approaches other than for-loop?


위의 문제에 대한 가장 간단한 해결책은 다음과 같습니다.

function range(from, to){
  const arr = [];

  for(let i = from; i <= to; i++){
    arr.push(i);
  }

  return arr;
}


Look at the problem statement again, we are not required to return an array, but something iterable would be fine as we'll be using the for...of loop.



이제 range 함수를 작성하여 2개의 숫자를 인수로 사용하고 iterable을 반환합니다.

// to make range() iterable
function range(from, to) {
  return {    
    [Symbol.iterator]: function(){
      // This returned object is known as the "iterator object" in the case of iterators and the "generator object" in the case of generators.
      return {
        from,
        to,

        next: function() {
          if(this.from <= this.to){
              return {value: this.from++, done: false}
          }else{
              return {done: true}
          }
        }
      }      
    }
  };
}

for (const item of range(1, 4)) {
  console.log(item);  
}


위의 코드에서 for...of 루프를 사용하여 반복하려고 할 때마다
  • 처음으로 Symbol.iterator 메서드를 한 번 호출하고 반복자 개체를 가져옵니다.
  • 다음에 for...ofnext 메서드를 사용하여 반복하는 동안 다음 값을 가져옵니다.

  • Don't confuse arrays with the iterators. Iterators are objects which implement the Symbol.iterator method in it. Arrays and strings have built-in iterators along with many other methods and properties, not necessarily other iterators would have the same.



    발전기



    제너레이터 함수는 "제너레이터 객체"라는 객체를 반환하며 그 안에 next 메서드가 있습니다.

    예시:

    function *generatorExample(){
      yield 1;
      yield 2;
    }
    
    const generatorObject = generatorExample();
    console.log(generatorObject.next()); // {value: 1, done: false};
    console.log(generatorObject.next()); // {value: 2, done: false};
    console.log(generatorObject.next()); // {value: undefined, done: true};
    

    next 메서드가 호출되면 첫 번째 yield까지 함수를 실행한 다음 실행을 일시 중지하고 2개의 속성을 가진 객체를 반환합니다.
  • 값: 산출 값.
  • done: 함수 실행이 완료되었는지 여부를 나타내는 부울입니다.

  • The generator functions can be identified by the * in function declaration, right after the function keyword(function*) or before the function name(function *name) without any space.



    위에서 언급한 동일한 문제는 다음과 같이 Generator 함수를 사용하여 매우 쉽게 해결할 수 있습니다.

    function range(from, to){
      return {
        [Symbol.iterator]: function* (){
          for(let i = from; i <= to; i++){
            yield i;
          }
        }
      }  
    }
    
    for (const item of range(1, 4)) {
      console.log(item);  
    }
    // 1
    // 2
    // 3
    // 4
    

    range 함수는 여전히 Symbol.iterator 메서드가 있는 객체를 반환합니다. 그러나 차이점은 Symbol.iterator가 현재 생성기 기능을 보유하고 있다는 것입니다. 그리고 우리가 알고 있듯이 제너레이터 함수는 자체적으로 next 메서드가 있는 제너레이터 객체를 반환합니다. 이 메서드는 반복자에 대해 명시적으로 구현해야 했습니다.

    Generators are also iterable.



    그런 다음 제너레이터와 함께 for...of 루프를 사용할 수 있습니다.

    function *generatorExample(){
      yield 1;
      yield 2;
    }
    
    const generatorObject = generatorExample();
    
    for(const item of generatorObject){
      console.log(item);
    }
    // 1
    // 2
    


    제너레이터도 반복 가능하므로 Symbol.iterator 메서드를 명시적으로 구현할 필요가 없으므로 솔루션을 더 단순화할 수 있습니다.

    function *range(from, to){
      for(let i = from; i <= to; i++){
        yield i;
      }
    }
    
    for (const item of range(1, 4)) {
      console.log(item);  
    }
    // 1
    // 2
    // 3
    // 4
    


    지금은 그게 다야 😀. 지금까지 읽어주셔서 감사합니다🙏.

    이에 대한 자세한 내용은 Iterators & generators - MDN 을 참조하십시오.

    이 블로그가 유용하다고 생각되면 네트워크와 공유하고 주제에 대해 의문이 있는 경우 언제든지 의견을 말하십시오.

    GitHub , , 에서 저와 👋 연결할 수 있습니다.

    좋은 웹페이지 즐겨찾기