💡 내 공부를 위한 Proxy 정리 글이다.
프록시란 무엇인가?
나는 Vue.js를 주로 작업하는 프론트 개발자이다.
Vue.js에서 객체를 콘솔로 찍을 때 순수하게 객체가 아닌 Proxy로 만들어진 값들을 마주할 때가 있다.
Proxy는 왜 쓰고? 어떻게 쓰는가? 이것에 대한 글이다.
Why use it?
대체 왜 프록시를 쓰는가?
프록시에 공부해보니 데이터가 변환되거나 읽어지거나 여러 경우에
프록시 트랩을 통해 제공하는 기능에서 유효성 처리나 변화를 감지할 때 사용 가능하다.
내가 실무에서 프록시를 써야하는 경우라면 어떻게 쓰겠는가?
- 객체를 set 해야 하는 경우 유효성 처리라던지
- get 해야 하는데 객체 내에 값이 없을 경우 default 값을 처리해줘야 한다던지
주요 데이터를 처리할 때 프록시를 쓰게 될 것 같다.
궁극적으로 프록시는 어떠한 라이브러리나 기능을 만들 때에 값이나 함수에 대한 재할당, 확장을 막고 전처리를 하는 등으로
객체를 보호하거나 휴먼 에러를 막는 수단으로 사용할 것 같다.
How use it?
먼저 프록시는 두가지로 나뉜다 실제 객체를 뜻하는 target과 트랩을 통해 동작을 가로채는 handler이다.
- target - 감싸는 객체 (실제 객체 또는 함수)
- handler - 동작을 가로채는 트랩(trap)이 담긴 객체
handler 에 작업과 같은 트랩(get, set…) 이 있으면 이를 통해 작업이 진행되고 없다면 target 에 바로 넘긴다.
Proxy 구현
const target = {}
const proxy = new Proxy(target, {}) // 빈 핸들러 {}
위와 같이 구현 시에는 Proxy 에 트랩이 없기 때문에 모든 작업은 바로 target 에 전달된다.
Trap
트랩으로 추가 가능한 핸들러 메서드는 아래 표에서 참고 할 수 있다. (참고)
내부 메서드 핸들러 메서드 작동 시점 규칙
get 활용
const handler = {
get : function(target, prop) {
return prop in target ? target[prop] : '값 없음'
}
}
const proxy = new Proxy({}, handler)
proxy.name = 'kate'
console.log(proxy.name) // kate
console.log(proxy.age) // 값 없음
set 활용 (값 재할당 막기)
const handler = {
// private 값은 set을 제한하고 public 값만 set을 허용한다.
set : function(target, key, value) {
if (key[0] === '_') {
return
}
target[key] = value
}
}
const test = {
_secret: '비밀 값',
publicValue: '공개 값',
}
has 활용
const handler = {
has : function(target, key) {
if(key[0] === '_') {
return false
}
return key in target
}
}
const test = {
_secret: '비밀 값',
publicValue: '공개 값',
}
const proxy = new Proxy(test, handler)
console.log('publicValue' in proxy) // true
console.log('_secret' in proxy) // false
let range = { begin:1, end: 10 }
range = new Proxy(range, {
has: function(target, prop) {
return prop >= target.start && prop <= target.end
}
})
console.log(5 in range) // true
console.log(50 in range) // false
isExtensible, preventExtensions 활용 (객체 확장 막기)
Reflect 란 target객체의 상태를 boolean 으로 리턴하는 여러 메서드를 가진 자바스크립트 기본 객체이다.
const test = {
isExtends: true
}
const handler = {
isExtensible : function(target) {
return Reflect.isExtensible(target) // 확장 여부를 판별
},
preventExtensions : function(target) {
target.isExtends = false
return Reflect.preventExtenstions(target) // target 객체에 새로운 속성을 추가하지 못하도록 막는 메서드
}
}
console.log(Object.isExtensible(test)) // true
Object.preventExtensions(test) // 확장 막기
console.log(Object.isExtensible(test)) // false
apply 활용
객체가 함수로 사용될 때 쓰기 좋은 메서드이다.
어떠한 함수가 호출될 때마다 로그를 찍거나 어떠한 사전 동작을 구현할 수 있다.
const handler = {
apply: function(target, thisArg, argumentsList) {
console.log('호출됨', argumentsList.join(', '))
return argumentsList[0] + argumentsList[1] + argumentsList[2]
}
}
const proxy = new Proxy(function(){}, handler}
console.log(proxy(1,2,3))
// 호출됨 1,2,3
// 6
이렇듯 프록시를 만들어 줌으로써 트랩의 활용으로 하나의 객체를 유틸리티 함수화 할 수 있다는 점 등이 프록시를 사용하는 이유이며 이로 인해 코드의 완성도를 높일 수 있다.
참고 :
'FRONT > javascript' 카테고리의 다른 글
Curry pattern (0) | 2024.03.06 |
---|---|
자바스크립트 (기초편) (0) | 2022.04.29 |
자바스크립트 (쌩기초편🤷🏻♀️) (0) | 2022.04.29 |
숫자 카운팅 모션 (정한 숫자와 시간에 맞게 올라가는 모션) (0) | 2021.07.05 |
Youtube API 다중 동영상 제어 (0) | 2021.07.01 |