-
프록시란 무엇일까?Javascript 2022. 10. 3. 20:54
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