본문 바로가기
FrontEnd/HTML5 & CSS & JavaScript

[JavaScript] Proxy 객체란?

by 푸고배 2022. 5. 6.

Proxy는 특정 객체를 감싸 프로퍼티 읽기, 쓰기와 같은 객체에 가해지는 작업을 중간에서 가로채는 객체로, 가로채진 작업은 Proxy 자체에서 처리되기도 하고, 원래 객체가 처리하도록 그대로 전달되기도 한다.

 

Proxy는 다양한 라이브러리와 몇몇 브라우저 프레임워크에서 사용되고 있다.

 

Syntax

new Proxy(target, handler);
  • target : 기본 동작을 가로챌, 즉 감싸게 될 객체로 함수를 포함해서 모든 객체가 가능하다.
  • handler :동작을 가로채는 메서드인 'trap'을 가지고 있는 객체로, 여기에서 프록시를 설정한다.

proxy에 작업이 가해지고, handler에 작업과 상응하는 트랩이 있으면 트랩이 실행되어 proxy가 이 작업을 처리할 기회를 얻게 된다. 트랩이 없으면 target에 작업이 직접 수행된다.

먼저, 트랩이 없는 프록시의 예시를 살펴보자.

let target = {};
let proxy = new Proxy(target, {}); // 빈 핸들러

proxy.test = 5; // 프락시에 값을 씁니다. -- (1)
alert(target.test); // 5, target에 새로운 프로퍼티가 생겼네요!

alert(proxy.test); // 5, 프락시를 사용해 값을 읽을 수도 있습니다. -- (2)

for(let key in proxy) alert(key); // test, 반복도 잘 동작합니다. -- (3)

위 예시의 proxy엔 트랩이 없기 때문에 proxy에 가해지는 모든 작업은 target에 전달된다.

1. proxy.test=를 이용해 값을 쓰면 target에 새로운 값이 설정된다.

2. proxy.test를 이용해 값을 읽으면 target에서 값을 읽어온다.

3. proxy를 대상으로 반복작업을 하면 target에 저장된 값이 반환된다.

 

객체에 어떤 작업을 할 때 자바스크립트 명세서에 정의된 '내부 메서드(interenal method)'가 관여하며, 프로퍼티를 읽을 때는 get, 쓸때는 set이라는 내부 메서드가 관여한다. 이런 내부 메서드들은 명세서에만 정의된 메서드이기 때문에 개발자가 코드를 사용해 호출할 수 없다. 

그림에서 볼 수 있듯이 트랩이 없으면 proxy는 target을 둘러싸는 투명한 래퍼가 된다.

Proxy는 '특수 객체(exotic object)'로 프로퍼티가 없으며 handler가 비어있으면 Proxy에 가해지는 작업은 target에 곧바로 전달된다. 

 

모든 내부 매서드에는 대응하는 트랩이 있으며 new Proxy의 handler에 매개변수로 추가할 수 있는 매서드 이름은 아래 표의 '핸들러 메서드' 열에서 확인할 수 있다.

내부 메서드 핸들러 메서드 작동 시점
[[Get]] get 프로퍼티를 읽을 때
[[Set]] set 프로퍼티에 쓸 때
[[HasProperty]] has in 연산자가 동작할 때
[[Delete]] deleteProperty delete 연산자가 동작할 때
[[Call]] apply 함수를 호출할 때
[[Construct]] construct new 연산자가 동작할 때
[[GetPrototypeOf]] getPrototypeOf Object.getPrototypeOf
[[SetPrototypeOf]] setPrototypeOf Object.setPrototypeOf
[[IsExtensible]] isExtensible Object.isExtensible
[[PreventExtensions]] preventExtensions Object.preventExtensions
[[DefineOwnProperty]] defineProperty Object.defineProperty, Object.defineProperties
[[GetOwnProperty]] getOwnPropertyDescriptor Object.getOwnPropertyDescriptor, for..in, Object.keys/values/entries
[[OwnPropertyKeys]] ownKeys Object.getOwnPropertyNames, Object.getOwnPropertySymbols, for..in, Object/keys/values/entries
규칙
내부 매서드나 트랩을 쓸 땐 자바스크립트에서 정한 몇 가지 규칙(invariant)을 반드시 따라야 한다.
대부분의 규칙은 반환 값과 관련되어있다.
- 값을 쓰는 게 성공적으로 처리되었으면 [[Set]]은 반드시 true를 반환해야 한다. 그렇지 않은 경우는 false를 반환해야 한다.
- 값을 지우는 게 성공적으로 처리되었으면 [[Delete]]는 반드시 true를 반환해야 한다. 그렇지 않은 경우는 false를 반환해야 한다.
이 외에 다른 조건도 있다.
- 프록시 객체를 대상으로 [[GetPrototypeOf]]가 적용되면 프록시 객체의 타깃 객체에 [[GetPrototypeOf]]를 적용한 것과 동일한 값이 반환되어야 한다. 프록시의 프로토타입을 읽는 것은 타깃 객체의 프로토타입을 읽는 것과 동일하게 한다. 

 

 


Reference

 

Proxy와 Reflect

 

ko.javascript.info

 

Home

yceffort

yceffort.kr

 

반응형

댓글