본문 바로가기
JavaScript

[스터디] JavaScript Proxy

by 복숭아 우유씨 2022. 10. 25.
 
 

Proxy 

Proxy 의 사전적 정의는 대리인, 대용물이다.

자바스크립트에서의 Proxy도 대리인처럼, 특정 객체를 감싸 객체에 가해지는 작업을 중간에 가로채고 재정의 한다.

 

문법

let p = new Proxy(target, handler)
  • Proxy: proxy객체 생성자
  • target : proxy할 원본 객체로 함수, 클래스, 다른 프록시 등 모든 객체 가능
  • handler : 동작을 가로채는 메서드인 '트랩(trap)'이 담긴 객체, 여기서 가로채는 작업과 가로채는 작업을 재정의하는 방법을 정의한다. 즉, 여기서 proxy 설정을 한다.
    • 트랩이 없는경우, target에 작업이 수행된다.
    • 트랩이 있는 경우, 트랩이 실행되어 proxy가 작업을 처리한다. 

 

사용하기

트랩의 역할

JS의 객체에 작업을 하면, 명세서에 정의된 내부 메서드가 관여하게 된다. 이 내부 메서드는 명세서에만 정의된 것으로 개발자가 호출할 수 없다. 그러나 Proxy의 트랩은 내부 메서드의 호출을 가로채서 대신 수행한다.

 

Proxy가 가로채는 내부 메서드 리스트는 명세서에 있으며, 각각의 내부 메서드에는 대응하는 트랩이 각각 있다. 아래 그림의 핸들러 메서드가 handler의 매개변수로 추가할 수 있는 이름이다.

javascript.info

이중 가장 대표적인 get과 set에 대해서 정리해보겠다.

 

get

- 프로퍼티 읽기를 가로챈다.

new Proxy(target, {
  get(target, property, receiver) {
  }
});
  • target : 동작을 전달할 객체
  • property : 가져올 속성의 이름 또는 Symbol
  • receiver : proxy 또는 proxy에 상속되는 객체, getter의 경우 getter가 호출될 때의 this.
  • 반환값: 어떤 값이든 반환 가능
let numbers = [0, 1, 2];

numbers = new Proxy(numbers, {
  get(target, prop) {
    if (prop in target) {
      return target[prop];
    } else {
      return 0; // 기본값
    }
  }
});

alert( numbers[1] ); // 1
alert( numbers[123] ); // 0 (해당하는 요소가 배열에 없으므로 0이 반환됨)

위의 예제와 같이 proxy로 객체를 감싸서, 속성에 접근하고 기본값을 설정할 수 있다.

 

 

set

- 프로퍼티 쓰기를 가로챈다.

new Proxy(target, {
  set(target, property, value, receiver) {
  }
});
  • target : 동작을 전달할 대상 객체
  • property : 설정할 속성의 이름 또는 Symbol
  • value : 설정할 속성의 새 값
  • receiver : 할당이 지시된 원래 객체, 일반적으로 프록시 자체
  • 반환값: 불리언 값 (할당 성공시 true,  엄격모드에서는 false 반환시 TypeError 예외 발생)
const p = new Proxy({}, {
  set(target, prop, value, receiver) {
    target[prop] = value;
    console.log(`property set: ${prop} = ${value}`);
    return true;
  }
})

console.log('a' in p);  // false (객체 p에 'a'가 존재하지 않음)

p.a = 10;               // "property set: a = 10"
console.log('a' in p);  // true
console.log(p.a);       // 10

 

 

 


References...

1) https://ko.javascript.info/proxy

2) https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Proxy 

3) https://patterns-dev-kr.github.io/design-patterns/proxy-pattern/

 

댓글