foodA를 갖는 target과 handler 객체를 이용해서 proxy를 생성하는 코드이다. 여기서는 handler에 특별한 내용은 설정하지 않았다.
그리고 target과 proxy를 통해서 주문을 진행해 보았는데 실행결과를 살펴보면 특별한 차이는 보이지 않는다. 두 경우 모두 김치찌개가 잘 주문되었다. 이럴 거면 Proxy를 사용한 의미가 없는데..
Handler와 Trap
proxy가 proxy 답게 동작을 가로채려면 handler의 개입이 필요하다. handler는 trap들을 가지는 placeholder 객체인데 여기서 trap이라는 용어가 중요하다. trap이란 target 객체의 property에 접근하기 위한 set/get 등 메서드로 이미 정의가 되어있다.
JavaScript에서는 console.log(target.food)와 같이 어떤 객체의 속성을 사용하면 property 값이 바로 반환되는 것이 아니라 [[Get]]이라는 내부 메서드가 호출된다. target.food='자장면'처럼 값을 변경할 때에도 [[Set]]이라는 내부 메서드가 호출된다.
Trap 중 get메서드는 target의 [[Get]]메서드에 대응하는 메서드이다. get Trap은 console.log(proxy.foodA)와 같이 접근했을 때 호출되며 target의 [[Get]]을 호출해 준다. 따라서 이 Trap 들을 사용하면 실제 target의 메서드가 호출되기 전에 끼어들기가 가능한 것이다.
다음은 내부 메서드와 매핑되는 handler의 trap 들이다.
내부 메서드
Trap method
내부 메서드
Trap method
내부 메서드
Trap method
[[Get]]
get
[[Set]]
set
[[OwnPropertyKeys]]
ownKeys
[[Construct]]
construct
[[Delete]]
deleteProperty
[[GetOwnProperty]]
getOwnPropertyDescriptor
[[HasProperty]]
Has
[[GetPrototypeOf]]
gegtPrototypeOf
[[DefineOwnProperty]]
defineProperty
[[IsExtensible]]
isExtensible
[[Call]]
apply
[[SetPrototypeOf]]
setPrototypeOf
자주 사용되는 trap 메서드
그럼 자주 사용되는 trap 메서드인 get과 set에 대해 살펴보자.
get
get은 target의 [[Get]]이 호출될 때 즉 속성을 사용할 때 proxy에서 호출되는 trap 메서드이다. handler에서 이 메서드를 미 구현하면 바로 [[Get]]이 호출된다.
다음은 get trap의 기본 syntax이다.
new Proxy(target, {
get: function(target, property, receiver) {}
});