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) {}
});