프록시 패턴은 실제 데이터에 접근할 수 있는 일종의 인터페이스(상속구조의 인터페이스가 아니다)를 만드는 디자인 패턴이다.
자바의 ORM인 JPA에서의 예를 들자면, FetchType.LAZY로 설정되어 있을 때, 어떤 엔티티 객체와 이어진 엔티티 프로퍼티는 '진짜' 객체가 아닌 임시 객체로 실제로 사용될 때 데이터베이스에서 값을 조회해 '진짜' 객체가 만들어진다.
ES6의 프록시는 JPA의 프록시와는 약간 다른 특성을 가진다. ES6의 프록시는 실제 객체와 핸들러 객체를 이용해 프로퍼티가 추가, 삭제, 변경 혹은 실행 될 때 특정 함수를 실행하는 객체를 만드는 클래스다.
class Person {
constructor(name) {
this.name = name;
}
}
const jack = new Person('JACK');
Person 클래스와 jack 객체 생성
const objHandler = { // 프록시 핸들러 객체
set : function (target, property, value, receiver) { // 대상 오브젝트 프로퍼티가 설정될 때
target[property] = `"proxy set ${value}"`;
return true;
},
get : function (target, property, receiver) { // 대상 오브젝트의 프로퍼티를 얻어올 때
return `"proxy get ${target[property]}"`;
}
};
프록시 객체의 프로퍼티의 핸들러 객체.
이 코드에서는 값이 설정될 때와 값을 가져올 때 값을 변경하도록 했다.
let objProxy = new Proxy(jack, objHandler); // 핸들러가 적용된 프록시 객체
objProxy.name = 'JOHN';
console.log(objProxy.name); // "proxy get "proxy set jack""
console.log(objProxy instanceof Person); // true
기반이 되는 객체와 핸들러 객체로 프록시 객체를 만들고 실행한 모습
위 코드는 간단한 핸들러 객체를 만들어 객체 프로퍼티의 값이 set / get 되었을 때 문자열을 추가하도록 구성했다. 간단한 예제 코드지만 ES6 프록시의 특성을 한눈에 파악할 수 있을 것이다. 핸들러 객체가 가로챌 수 있는 'trap'의 목록은 아래와 같다.
Handler method |
Object method |
getPrototypeOf |
Object.getPrototypeOf() |
setPrototypeOf |
Object.setPrototypeOf() |
isExtensible |
Object.isExtensible() |
preventExtensions |
Object.preventExtensions() |
getOwnPropertyDescriptor |
Object.getOwnPropertyDescriptor() |
defineProperty |
Object.defineProperty() |
has |
Object.has() |
get |
Object.get() |
set | Object.set() |
ownKeys | Object.ownKeys() |
apply | Object.apply() |
construct | Object.construct() |
trap의 목록에서 알 수 있듯 Proxy 클래스는 Object의 기본 메소드들을 오버라이딩한다.
더 자세한 정보와 다른 트랩을 사용한 예제를 보려면 모질라 제단 홈페이지를 참고하자.
'ECMAScript | TypeScript' 카테고리의 다른 글
ECMAScript, 배열의 splice와 slice 메소드 (0) | 2017.09.27 |
---|---|
ECMAScript 5.1로 만든 조합(Combination) 함수 (0) | 2017.09.13 |
ECMAScript, 딕셔너리와 Map (0) | 2017.08.21 |
ECMAScript, Function.prototype의 bind 함수(this 지정, 커링) (0) | 2017.08.17 |
Typescript의 Decorator - 2. Property Decorator, 간단한 Dependency Injection (0) | 2017.08.15 |