Generators

Generators함수는 function뒤에 *를 추가하여 지정할 수 있다. 그리고 generators로 진정된 함수는 async, await처럼 yield라는 특별한 키워드를 호출할 수 있다. yield는 함수의 return과 비슷한 동작을 하지만 generators.next()로 yield에 지정된 데이터에 접근하는것에 차이점이 있다.

<aside> 📝 Generators function

function* func(){yield}

function* sayHi(){yield "Hi"}
const variable = sayHi();
variable.next();
// {value: 'Hi', done: false}

</aside>

Next함수를 사용하여 generators함수가 반환할 데이터 값을 차례로 yield를 통해 가져올 수 있게 할 수 있다. 드리고 yield를 등록한 만큼도 가져올 수 있다.

/**
 * Generators를 사용하는 방법은 function뒤에 `*`을 달아주면 된다.
 * `yield`로 return과 비슷한 작업을 수행 할 수 있다.
 */
function* listPeople() {
  yield "Dal";
  yield "Flynn";
  yield "Mark";
  yield "Godkimchi";
  yield "Japan Guy";
}

/**
 * Generators를 호출하면 yield와 관련된 데이터가 출력되지 않는데
 * `.next()`를 호출하여 yield순서대로 지정한 데이터에 접근할 수 있다.
 */
const listG = listPeople();

/**
 * yield를 반복문안에 정의하여 다양한 방법으로 yield를 호출할 수 있다.
 */
const friends = ["Dal", "Flynn", "Mark", "Godkimchi", "Japan Guy"];
function* friendTeller() {
  for (const friend of friends) {
    yield friend;
  }
}
const friendLooper = friendTeller();

Proxies

Object에 filter을 설정하여 object의 동작을 정의하는 객체로 proxy가 있다. Proxy는 object의 API가 호출되면 동작하는 event를 헨들러를 통해 재정의하여 object의 API 동작을 바꿀 수 있다. 헨들러는 object형태이며 API를 재정의하는 property를 trap이라 부른다.

<aside> 📝 Description proxy

const variable = new Proxy(target,handler)

const userObj = {
  username: "nico",
  age: 12,
  password: 1234,
};
const filteredUser = new Proxy(userObj, {});

</aside>

기본적으로 Proxy 인스턴스는 target에 전달된 object 데이터를 가지고 생성이 되지만, 정의된 handler object를 받게되면 그에 맞추어 object 동작을 다르게한다. MDN으로 가서 Proxy 핸들러에 관한 문서를 참고하여 사용하자.

/**
 * Proxy는 filter처럼 생각할 수 있다. Proxy객체는 object와 그 object를
 * 제어하는 헨들러 인수를 받는다. 그리고 아래 처럼 핸들러 역할을 할 object를
 * 비워두고 `filteredUser`변수를 object propety를 호출하는거첨 접근하면
 * object값을 받아 올 수 있다.
 */
const userObj = {
  username: "nico",
  age: 12,
  password: 1234,
};
const userFilter1 = {};
const filteredUser1 = new Proxy(userObj, userFilter1);

/**
 * 하지만 헨들러 역할을 하는 object에 get과 set을 정의하여 변수에 요소접근을
 * 시도하면 get이 호출이되고 변수에 요소를 새롭게 정의하면 set이 호출이된다.
 * 물론 새로 정의한 요소도 추가되지 않는걸 확인할 수 있다.
 * 기본적으로 proxy객체의 요소를 가지고 오는 방법은 get에 다음과 같이 정의하여
 * 가지고 오는 방법을 한다. `return target[prop];` 또한 삼항 연산자나 다른
 * 정의로 요소를 가공하여 출력할 수도 있고 데이터를 변형시킬 수 있다.
 */
const userFilter2 = {
  get: (target, prop, receiver) => {
    return prop == "password" ? `*`.repeat(5) : target[prop];
  },
  set: () => {
    console.log(`Somebody wrote something`);
  },
  deleteProperty: (target, prop) => {
    if (prop == "password") {
      return;
    } else {
      target[prop] = "DELETE";
    }
  },
};
const filteredUser2 = new Proxy(userObj, userFilter2);

Should you learn proxies or generators?

Proxy나 generator같은 기술들은 일반 프로그래머가 사용하기에는 그닥 효용성이 없다. 보통은 API나 라이브러리 설계자들이 사용하는 부분이기에 앞으로 백엔드로 개발할 기회가 있다면 이러한 기술들이 JS module을 개발함에 있어 도움이 될 것이다.