Javascript에서 Proxy를 다루는 내용들이 있습니다.
Proxy란 무엇이고 어떻게 사용해야 할까요?
ECMAScript 6에서 정의되어진 Proxies에 대해서 알아보고 사용법을 익혀보는 시간을 가져 보시죠 : )
프록시란 무엇일까
MDN의 문서의 내용과 같이 프록시 객체는 다른 객체에 대한 프록시를 만들고, 이 객체는 해당 객체에 대한 기본 작업을 가로채고 재정의할 수 있는 작업들을 할 수 있다는 것입니다.
다시말하면, 그 객체는 해당 객체를 래핑하고, 그 객체를 재정의하고 사용할 수 있는 것입니다.
일반적으로, 이러한 작업들을 우리는 객체를 가져와서 숨겨진 게이트웨이를 생성하고 원하는 객체에 대한 모든 액세스를 제어할 수 있도록 프록시로 포장한다는 것을 의미합니다.
프록시는 두개의 파라미터로 만들어집니다.
- target : 감싸고 싶은 원본 객체
- handler : 가로채는 작업을 재정의하는 방법을 정의하는 메서드
const target = {
name: "noel",
region: "incheon"
};
const handler = {};
const proxy = new Proxy(target, handler);
프록시는 대부분의 브라우저에서 지원되고, 지원하지 않는 오래된 브라우저들은 폴리필로 대체 가능합니다.
프록시 사용법
만약에 A 편의점에 포켓몬 빵의 재고가 변경될 때마다 알림을 받고 싶습니다.
그러면 프록시를 사용해서 어떻게 할 수 있을까요?
const convenientStore = {
count: 10,
name: '포켓몬 빵'
};
const handler = {
get: function(target, prop, receiver) {
if (prop === 'count') {
console.log(`현재 ${target.name}의 개수 : ${target.count} 개`);
}
return target[prop];
}
};
const wrappedConvenientStore = new Proxy(convenientStore, handler);
wrappedConvenientStore.count;
// 결과
// 현재 포켓몬 빵의 개수 : 10 개
// 10
위의 예시로부터 우리는 handler를 통해서 포켓몬 빵의 count에 접근했을 때 현재 포켓몬 빵의 개수가 10개라는 것을 알 수 있었습니다.
다음 예시는 3개의 파라미터를 받습니다.
우리는 위의 A 편의점에서 누군가가 포켓몬 빵을 사갔을 때 알림을 받기를 원합니다.
그리고 또 다른 제약사항으로 편의점은 포켓몬 빵이 0개 미만으로는 내려갈 수 없다는 것 입니다.
이를 위해서 handler/trap을 사용하겠습니다.
const convenientStore = {
count: 10,
name: '포켓몬 빵'
};
const handler = {
set: function(obj, prop, value) {
console.log(`현재 ${obj.name}의 개수 : ${obj.count} 개`);
if (value < 0) {
console.log(`포켓몬 빵은 0개 미만이 될 수 없습니다`);
return false;
}
obj[prop] = value;
return true;
}
};
const wrappedConvenientStore = new Proxy(convenientStore, handler);
wrappedConvenientStore.count -= 5;
console.log(wrappedConvenientStore.count);
wrappedConvenientStore.count -= 25;
console.log(wrappedConvenientStore.count);
// 현재 포켓몬 빵의 개수 : 10 개
// 5
// 현재 포켓몬 빵의 개수 : 5 개
// 포켓몬 빵은 0개 미만이 될 수 없습니다
// 5
위와 같이 더 이상 감소할 수 없다면 return false를 통해서 작업을 중단할 수 있습니다.
프록시를 사용하고 있는 기술들
많은 기술들이 Proxies를 사용하고 있습니다.
Mobx라던지, Vue, Immer와 같은 상태관리 라이브러리 등이 사용중입니다.
변화가 감지되어 반영되게 만들어야하는 양방향 바인딩을 위한 상태 감지 등 가로채고 재정의하는 모든 메서드에서 사용됩니다.
예시
위에서 사용했듯이 로그로도 사용할 수 있고, 유효성 검사로도 작용할 수 있을 것 같네요.
캐싱적용
캐싱 적용을 해봅니다.
const convenientStore = {
count: 10,
name: '포켓몬 빵',
get price() {
console.log('빵의 가격');
return this.count * 1000;
}
};
let cache = {
currentCount: null,
currentValue: null
}
const handler = {
get: function(obj, prop) {
if (prop === 'price') {
let value = cache.currentCount !== obj.count ? obj[prop] : cache.currentValue;
cache.currentValue = value;
cache.currentCount = obj.count;
return value;
}
return obj[prop];
}
};
const wrappedConvenientStore = new Proxy(convenientStore, handler);
console.log(wrappedConvenientStore.price);
console.log(wrappedConvenientStore.price);
console.log(wrappedConvenientStore.price);
console.log(wrappedConvenientStore.price);
// 빵의 가격
// 10000
// 10000
// 10000
// 10000
DOM 조작
상태가 변경될 때마다 화면의 값들을 업데이트 하고 싶습니다.
set operator/trap을 사용해서 해봅니다.
const convenientStore = {
count: 10,
name: '포켓몬 빵',
get text() {
return `${this.name}의 개수는 ${this.count}개 입니다.`;
}
};
const domManipulate = (object, domId) => {
const handler = {
set: function(obj, prop, value) {
obj[prop] = value;
document.getElementById(domId).innerHTML = obj.text;
return true;
}
};
return new Proxy(object, handler);
}
const wrappedConvenientStore = domManipulate(convenientStore, "domId");
wrappedConvenientStore.count = 300;
wrappedConvenientStore.count = 500;
See the Pen Proxy by YoungMinKim (@oinochoe) on CodePen.
Proxy에 대해서 알아가는 시간이 되셨기를 바랍니다 : )
출처 : https://levelup.gitconnected.com/the-amazing-power-of-javascript-proxies-aa27c6d06bcb
'Javascript' 카테고리의 다른 글
ES12(ES2021)의 최고의 3가지 기능 (0) | 2022.10.10 |
---|---|
Axios 인터셉터를 사용하는 4가지 방법 (0) | 2022.10.10 |
파비콘 동적으로 변경하기 (0) | 2022.09.25 |
[Javascript] Try/Catch, Error를 다루는 방법 (0) | 2022.09.12 |
미디어쿼리를 자바스크립트에서 사용해야될 때 (0) | 2021.10.05 |
댓글