๐Ÿ“ Weekly I Learned

๐Ÿฆ What is the Iterator

  • In JavaScript an iterator is an object which defines a sequence and potentially a return value upon its termination. by MDN

๐ŸŠ Iterator interface

  1. next๋ผ๋Š” ํ‚ค๋ฅผ ๊ฐ–๊ณ 
  2. ๊ฐ’์œผ๋กœ ์ธ์ž๋ฅผ ๋ฐ›์ง€ ์•Š๊ณ  IteratorResultObject๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ ์˜จ๋‹ค.
  3. IteratorResultObject๋Š” value์™€ done์ด๋ผ๋Š” ํ‚ค๋ฅผ ๊ฐ–๊ณ  ์žˆ๋‹ค.
  4. ์ด ์ค‘ done์€ ๊ณ„์† ๋ฐ˜๋ณตํ• ์ˆ˜ ์žˆ์„์ง€ ์—†์„์ง€์— ๋”ฐ๋ผ Boolean๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

์œ„ 4๊ฐ€์ง€ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋ฉด Iterator ๊ฐ์ฒด๋ผ๊ณ  ๋ด…๋‹ˆ๋‹ค.

    {
        data:[1,2,3,4],
        next() {
            return {
                done: this.data.length == 0,
                value: this.data.pop()
            };
        }
    }

๐Ÿฆ Iterable Interface

  1. Symbol.iterator๋ผ๋Š” ํ‚ค๋ฅผ ๊ฐ–๊ณ 
  2. ์ด ํ‚ค๋Š” ๊ฐ’์œผ๋กœ ์ธ์ž๋ฅผ ๋ฐ›์ง€ ์•Š๊ณ  Iterator Object๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค.
     {
             arr: [1,2,3,4],
             [Symbol.iterator](){return this;},
             next() {
                 return {
                     done: this.arr.length == 0,
                     value: this.arr.pop()
                 };
             }
     };
    

    ๐Ÿฟ Why use the Iterator?

  • for๋‚˜ while๋ฌธ ๊ฐ™์€ ๋ฐ˜๋ณต๋ฌธ์€ '๋ฌธ'์ด๊ธฐ ๋•Œ๋ฌธ์— ํ•œ๋ฒˆ ๋ฐ˜๋ณต์ด ๋๋‚˜๊ณ  ๋‚˜๋ฉด ๋‘๋ฒˆ ๋‹ค์‹œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.
  • Iterator์€ ๋ฐ˜๋ณต๋ฌธ์„ '์‹'์ด๋‚˜ '๊ฐ’'์œผ๋กœ ๊ณ„์† ์œ ์ง€ ์‹œ์ผœ์ฃผ๊ธฐ ์œ„ํ•œ ๋„๊ตฌ(๋ฐ˜๋ณต ์ „์šฉ ๊ฐ์ฒด)
  • ์œ„ ์˜ˆ์ œ์˜ ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋Š” ๋ฐ˜๋ณต ์ž์ฒด๋ฅผ ํ•˜์ง€๋Š” ์•Š์ง€๋งŒ ์™ธ๋ถ€์—์„œ ๋ฐ˜๋ณต์„ ํ•˜๋ ค๊ณ  ํ•  ๋•Œ ๋ฐ˜๋ณต์— ํ•„์š”ํ•œ ์กฐ๊ฑด๊ณผ ์‹คํ–‰์„ ๋ฏธ๋ฆฌ ์ค€๋น„ํ•ด ๋†“๊ณ  ๊ทธ๊ฒƒ์˜ ๋ณต์‚ฌ๋ณธ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • ์ฆ‰, ๋ฐ˜๋ณต ํ–‰์œ„์™€ ๋ฐ˜๋ณต์„ ์œ„ํ•œ ์ค€๋น„๋ฅผ ๋ถ„๋ฆฌํ•˜์—ฌ, ๋ฏธ๋ฆฌ ๋ฐ˜๋ณต์— ๋Œ€ํ•œ ์ค€๋น„๋ฅผ ํ•ด๋‘๊ณ  ํ•„์š”ํ•  ๋•Œ ํ•„์š”ํ•œ ๋งŒํผ ๋ฐ˜๋ณต ์‹œํ‚ค๋Š” ๊ฒƒ์„ ์žฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋ฐ˜๋ณต ํ–‰์œ„๋Š” next() ํ˜ธ์ถœ๋กœ ์ด๋ฃจ์–ด ์ง„๋‹ค.
  • ์‚ฌ์šฉ์ž ๋ฐ˜๋ณต ์ฒ˜๋ฆฌ๊ธฐ Example

      const loop = (iter, f) => {
          //Iterable์ด๋ผ๋ฉด Iterator๋ฅผ ์–ป์Œ 
          if(typeof iter[Symbol.iterator] == 'function') {
              iter = iter[Symbol.iterator]();    
          }else return;
    
          //IteratorObject๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ๊ฑด๋„ˆ๋œ€ 
    
          if(typeof iter.next != 'function') return;
    
          do {
              const v = iter.next();
              if(v.done) return; // ์ข…๋ฃŒ ์ฒ˜๋ฆฌ
              f(v.value); // ํ˜„์žฌ ๊ฐ’์„ ์ „๋‹ฌํ•จ. ๋ฐ˜๋ณต์‹œ ๋งˆ๋‹ค ์ฒ˜๋ฆฌํ•ด์•ผํ•˜๋Š” ํ•จ์ˆ˜ ํ˜ธ์ถœ
          }while(true) // ๋ฐ˜๋ณต๊ธฐ ์ •์˜ ์ด while๋ฌธ์€ ๋ฌดํ•œ๋ฃจํ”„๋กœ ๊ทธ๋ƒฅ ๋ฐ˜๋ณต์ด๋ผ๋Š” ํ–‰์œ„๋งŒ ํ•œ๋‹ค. 
      };
    
      const iter = {
          arr: [1,2,3,4],
          [Symbol.iterator](){return this;},
          next() {
              return {
                  done: this.arr.length == 0,
                  value: this.arr.pop()
              };
          }
      };
    
      loop(iter, console.log);
      // 4, 3, 2, 1
    

    ๐Ÿ‚ Can use Es6+ operator When use the Iterator

  • Array destructuring
  • Spread operator
  • Rest operator
  • For ~ of

๐Ÿฆ‘ What is the Generator?

  • The Generator object is returned by a generator function and it conforms to both the iterable protocol and the iterator protocol. by MDN
  • ์‰ฝ๊ฒŒ ๋งํ•˜์ž๋ฉด ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ์ฝ”๋“œ๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์œผ๋‹ˆ๊นŒ ์‰ฝ๊ฒŒ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ ์‚ฌ์šฉํ•œ๋‹ค.

      // Iterator
      const N2 = class {
          constructor(max) {
              this.max = max;
          }
          [Symbol.interator](){
              let cursor = 0, max=this.max;
              return {
                  done: false,
                  next() {
                      if(cursor > max) {
                          this.done = true;
                      } else {
                          this.value = cursor * cursor;
                          cursor++;
                      }
                      return this;
                      }
                  };
              }
      };
    
      // Generator
      const generator = function* (max) {
          let cursor = 0;
          while(cursor < max) {
              yield cursor * cursor;
              cursor++;
          }
      };
    

    ๐Ÿ› How to use Generator?

  • function* (){} ์ธ Generator ์ƒ์„ฑ ๋ฆฌํ„ฐ๋Ÿด์„ ์ด์šฉํ•ด์„œ ์ƒ์„ฑํ•œ๋‹ค.

  • Generator๋Š” ์ƒ์„ฑ ๋ฆฌํ„ฐ๋Ÿด์— ์ •์˜๋œ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๋ฏ€๋กœ ์ง€์—ญ๋ณ€์ˆ˜์™€ ์ธ์ž๋ฅผ ๊ฐ€์ง€๊ณ  ์ผ๋ฐ˜์ ์ธ ์ œ์–ดํ๋ฆ„์„ ๋”ฐ๋ฅธ๋‹ค.
  • ํ•จ์ˆ˜์— ์ธ์ž์™€ ์ง€์—ญ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ œ์–ด๋ฌธ์„ ์‚ฌ์šฉํ•˜๊ณ ์žˆ๋Š” ์ผ๋ฐ˜์ ์ธ ๋™๊ธฐํ™” ํ๋ฆ„ ํ”Œ๋กœ์šฐ ๊ตฌ์กฐ๋ฅผ ๋”ฐ๋ฅด๊ณ  ์žˆ๋‹ค. ์œ ์ผํ•˜๊ฒŒ ๋‹ค๋ฅธ๊ฑด yield๊ฐ€ ๋“ฑ์žฅํ•˜๊ณ  ์žˆ๋‹ค.
  • yield๋ฅผ ํ˜ธ์ถœํ• ๋•Œ๋งˆ๋‹ค Iterator์˜ next() ๊ฐ€ ๋ฐ˜ํ™˜๋˜๋Š” ๊ฒƒ๊ณผ ๋˜‘๊ฐ™์€ ํšจ๊ณผ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
  • Iterator์™€ ๋‹ค๋ฅธ ์ ์€ yield๋ฅผ ๋งŒ๋‚˜๋ฉด ํ•จ์ˆ˜๊ฐ€ ๊ทธ ์ž๋ฆฌ์—์„œ ๋ฉˆ์ถ”๊ณ  Iterator์˜ result๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ, Generator ๊ฐ์ฒด๊ฐ€ next()๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ๋‹ค์‹œ ๋ฉˆ์ถ˜ ์ง€์ ์—์„œ ๋™์ž‘ํ•œ๋‹ค.
  • Generator์—์„œ yield๋ฅผ ๋งŒ๋‚˜๋Š” ๋™์•ˆ์€ done: false๋ฅผ ์œ ์ง€ํ•˜๋ฉฐ, Generator๋ฅผ ๋น ์ ธ๋‚˜๊ฐˆ ๋•Œ done: true๊ฐ€ ๋œ๋‹ค.

๐Ÿฆ• ๋งˆ์น˜๋ฉฐ...

  • ์ด ๊ธ€์˜ ๋ชจ๋“  ์˜ˆ์ œ์™€ ๋‚ด์šฉ์€ ์ฝ”๋“œ์Šคํ”ผ์ธ  youtube์™€ bsidesoft ์‚ฌ์ดํŠธ์˜ Generaotr ๊ธ€์—์„œ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.