javascript에서 generator는 무엇인가요?

AtoZ·2023년 5월 15일
0

자바스크립트

목록 보기
1/1

🤔 개요

안녕하세요 😀
요즘 기술 면접을 통해서 많이 배우고 있습니다.
그중 오늘은 기술 면접 중에 질문받았던 재미있는 내용이 있어 그와 관련된 포스팅을 하려고 합니다.

🔍 프론트 엔드 영역에서 generator를 사용하는 곳이 어딨을까요?

위의 질문은 모 회사 기술면접에서 받았던 질문입니다.
저의 답변은 상태 관리 Redux에서 비동기 컨트롤을 위한 미들웨어 Redux-saga 에서 사용한다고 답변한 후 아래와 같은 추가 질문을 받았습니다.

Redux-saga 이 외에 또 어디서 사용할까요?

저는 답변을 하지 못했습니다.
면접 후 이 부분이 너무 궁금해서 복기하는 와중에 새로운 사실을 알게 됐습니다.

저는 일전에 Redux-saga 사용하면서 javascript에 generator 문법은 마치 Redux-saga를 위한 문법 같다는 생각을 했습니다. Redux-saga 외에는 사용하지 않을거라고 생각했었는데 이 부분이 제가 답변하지 못한 이유였습니다.

결론을 말씀 드리면 generator는 iterator 입니다. iterator는 map, set, list 같은 반복 가능한 객체를 생성하는 특별한 인터페이스입니다.

📌 나만 몰랐던 Generator(=Iterator) 사용처

위에서 generator = iterator는 알게 됐습니다.

"그러면 실제 어떤 상황에서 iterator가 사용되고 있을까요❓"

[예시1]

const set = new Set([1,2,3,4])

for(const a of set) console.log(a);

[예시2]

const set = new Set([1,2,3,4])

for(let i=0;i<set.size;i++) console.log(set(i));

예시1예시2 의 결과는 같을까요❓

답은 다르다 입니다.
for~of 연산자는 마치 배열을 순회하면서 값을 출력해 주기 때문에 예시2 처럼 set을 index로 접근하여 가져오려고 할 수 있지만 set은 list도 아니고 특정 값을 get 하는 함수도 없습니다.(forEach나 커스텀 함수를 만들어야 한다.)

그러면 어떻게 예시1 처럼 사용할 수 있을까요❓

그거는 Symbol.interator 함수에 의해서 가능합니다.

위의 사진은 Set 객체의 prototype 입니다. 그중 Symbol.iterator 라는 함수를 보실 수 있는데 이 부분을 통해서 set 객체를 for~of를 통해 값을 추출할 수 있었던 것입니다
Symbol.iterator를 어떻게 사용하고 어떤 구현부를 가지고 있는지 자세히 보겠습니다.

const set = new Set([1,2,3,4])

const iterator = set[Symbol.iterator]();

console.log(iterator.next());   //{value: 1, done: false}
console.log(iterator.next());   //{value: 2, done: false}
console.log(iterator.next());   //{value: 3, done: false}
console.log(iterator.next());   //{value: 4, done: false}
console.log(iterator.next());   //{value: undefined, done: true}

set 객체에 정의된 Symbol.iterator 메소드를 통해 iterator 객체를 추출하여 next() 함수를 통해 {value, done} 구조의 객체를 추출하였습니다.

그러면 "Symbol.iterator 는 구현부가 어떻길래 이런 형태의 객체를 return 해주는거지❓"라고 궁금하실겁니다.(안궁금해도...궁금하다고 해주세요^^ 저는 궁금했거든요 ㅎㅎ)
Symbol.iterator 의 구현부를 살펴보겠습니다.

const myIterable = {
  data: [1, 2, 3],
  index: 0,
  [Symbol.iterator]() {
    // 이터레이터 객체를 반환
    return {
      next: () => {
        // 값을 생성하고 반복을 제어하는 next() 메서드를 구현
        if (this.index < this.data.length) {
          return {
            value: this.data[this.index++],
            done: false,
          };
        }
           return {
            done: true,
          };
      },
      //Symbol.iterator iterable을 전역으로 iterator를 사용하기 위한 코드
      [Symbol.iterator](){return this}
    };
  },
};

위의 코드는 Symbol.iterator 를 쉽게 설명하기 위한 예제 코드입니다. next() 함수를 통해 주어진 자료를 순회할 수 있는 형태로 가공하여 return 시켜줍니다.

이런 내부 구현을 가지고 있어서 list 형태가 아닌 set, map등을 for...of 를 통해 쉽게 순회할 수 있었던 것입니다. 이것을 가능하게끔 하는 기술이 iterator 입니다.

이 부분 외에도 또 사용되는 곳이 있습니다.

[예시1]

const list1 = [1,2]
const list2 = [3,4]

console.log([...list1, ...list2]) 

[예시2]

const list1 = [1,2]
const list2 = [3,4]

list[Symbol.iterator]() = null;

console.log([...list1, ...list2]) 

예시1예시2은 결과가 같을까요❓
답은 다르다 입니다.
예시2 코드의 결과는 유효하지 않은 값이라는 에러를 반환합니다.

위의 예시 코드를 해석하면 Symbol.iteratornull로 값을 재할당하니 스프레드 문법을 사용할 수 없게 됐습니다. 다르게 말하면 스프레드 문법 또한 iterator를 활용하고 있다가 될 수 있습니다.

이렇게 저희가 흔하게 사용하던 문법들이 내면에는 iterator(generator)를 사용하고 있다는것을 알게됐습니다.

🫡 마무리

현재 재직 중인 회사의 Tech Lead, CTO 분들은 제가 합류했을 때부터 이직을 하지 않더라도 주기적으로 면접은 보는 게 좋다고 말씀해 주셨습니다. 면접을 보면서 기술적으로 부족한 부분이 무엇인지 알게 되고 기술적으로 얼마나 발전했는지 알 수 있는 등 다양한 관점에서 이득이 있다고 말씀해 주셨습니다.

그때 당시에는 이해가 되질 않았는데 요즘 면접 보면서 공감하고 있습니다. 기술면접을 통해 부족한 부분이 무엇인지 많이 알게 되는 기회였습니다.

그래서 혹시나 이 글을 읽고 계신 독자분들도 번아웃이 왔다거나 또는 스스로 얼마나 발전했는지 모르실 때 기술면접을 보는 것도 좋은 방법 중 하나라고 말씀드리고 싶습니다.

profile
코딩으로 글쓰는 작가

0개의 댓글