Proxy

JJ·2023년 5월 28일
0

자바스크립트

목록 보기
4/5
post-thumbnail

Proxy

오늘은 우리나라 사람이라면, 한번쯤 들어봤을 법한 Proxy에 대해 알아보려고 한다. 웹 개발을 공부하면서, 대부분의 용어는 한번도 들어보지도 보지도 못한 것들이었지만, 이녀석은 왠지(?) 친숙했다. 물론, 이 글을 작성하기 전에는 그저 우리나라에서 접속하지 못하는 사이트를 들어가기 위해 프록시 서버로 우회해서 들어갈 수 있다는 것 정도로만 알고 있었다.

Proxy는 사전적 의미로 '대리인'이라는 뜻을 가지는데, 그 뜻 처럼 나 대신에 데이터를 주고 받아 주는 개념이다. 일반적으로 웹에서 통신이 일어나면 클라이언트 사이드와 서버 사이드 간에 통신이 일어나는데, 이때, Proxy가 있다면, 나 대신에 서버와 통신을 하는 것처럼 보여지는 것이다. 물론, 이번 글에선 자세한 원리는 다루지 않을 예정이다.

자바스크립트에는 Proxy라는 빌트인 객체가 존재한다. 앞서 소개한 proxy는 어떠한 작업에서 나와 상대방이 다이렉트로 소통하는 것이 아니라 대리인을 내세워서 대신 해주는 역할을 하고 있었는데, mdn에서 proxy에 대해 '한 객체에 대한 기본 작업을 가로채고 재정의할 수 있다.'라고 소개하고 있다. 즉, 다시말해서 무언가를 가로채서 대신 해준다는 점에서 유사하다고 생각된다.

사용법

const target = {
  message1: "hello",
  message2: "world"
};

const handler = {
  get(target, prop, receiver) {
    return "hi";
  }
}

const proxy = new Proxy(target, handler);

console.log(proxy.message1); // hi
console.log(proxy.message2); // hi

가로채려는 원본 객체인 target과 가로채는 방법과 재정의하는 방법을 정의하는 handler 객체를 매개변수로 받아서, proxy 객체를 만들 수 있다. 위의 예시에서는 handler 객체에 get() 처러기(다른 말로 trap 이라고도 함)를 적용하여 target의 프로퍼티 값을 재정의하였다.

handler (trap)

Proxy 객체의 handler 객체의 처리기에는 대표적으로 get()과 set()이 있다. 이외에도 여러가지 메서드들이 많으므로, 여기를 참고해보자.

handler.get()

target 객체의 값을 읽기 위해, 매개변수로 target, property, receiver가 들어온다.

target: new Proxy() 의 첫번째 인자로 넘겨준 원본 객체(처리해주려는 대상 객체)

prop: 조회하려는 property의 이름 또는 Symbol

reciever: 프록시 또는 프록시에서 상속되는 객체

handler.set()

target 객체의 속성 값을 변경하기 위해 사용되며, 매개변수로는 target, property, value, receiver가 들어온다.

target: new Proxy() 의 첫번째 인자로 넘겨준 원본 객체(처리해주려는 대상 객체)

prop: 조회하려는 property의 이름 또는 Symbol

value: 변경할 속성의 새로운 값

reciever: 프록시 또는 프록시에서 상속되는 객체

아래의 예시를 보면서 이해해보자.

const person = {
  name: 'jj',
  age: 33
};

const proxy = new Proxy(person, {
  get(target, prop) {
    if (prop in target) {
      return target[prop];
      // return Reflect.get(target, prop);
    } else {
      throw new Error(`Property "${prop}" does not exist.`);
    }
  },
  set(target, prop, value) {
    if (typeof value !== 'number') {
      throw new TypeError('Value type must be number.');
    } else {
      target[prop] = value;
      // return Reflect.set(target, prop, value);
    }
  }
})

우선, person이라는 원본의 객체가 있고, 아래에 proxy라는 Proxy 객체를 생성하고, 이 객체에는 get과 set handler가 정의되어 있다. 먼저 get handler 에선 target 객체 즉, person 객체를 말하고, 이 객체에 prop이 존재한다면, 그 값을 반환하고, 없다면 에러를 발생시킨다. 그리고, set handler 에선 숫자 이외의 값이 할당된다면 에러가 발생하고, 그렇지 않다면 정상적으로 값이 할당되도록 작성되어 있다. 이와 같이 Proxy 객체를 사용해서 객체에 대한 접근과 변경에 대한 로직을 커스텀화 할 수 있음을 알 수 있다.

대개 Proxy 객체를 사용할 때, 위의 예시에서 주석처리 해놓은 Reflect를 사용하는 것을 볼 수 있다. Reflect는 자바스크립트에서 제공하는 내장 객체로, Proxy 객체와는 다르게 생성자로 사용할 수 없다. 즉, Reflect의 모든 속성과 메서드는 static하다는 의미이다. 따라서, 코드의 흐름상 명시적으로 사용되는 경우가 많다고 한다.

Reference

profile
한줄 한줄

0개의 댓글