728x90
반응형
**Proxy**는 **ES6(ECMAScript 6)**에서 도입된 기능으로, **객체의 기본 동작(프로퍼티 접근, 값 할당, 함수 호출 등)**을 가로채서 제어하거나 수정할 수 있게 해주는 강력한 도구임. Proxy를 사용하면 객체에 대한 커스텀 동작을 정의할 수 있으며, 특정 상황에 맞는 동작을 추가하거나 객체의 기본적인 동작 방식을 바꿀 수 있음.
1. Proxy의 기본 개념
Proxy는 두 개의 인자를 받음:
- 타겟 객체(target): 감시하거나 가로채고 싶은 원래 객체.
- 핸들러(handler): 객체의 동작을 가로채고 **수정할 트랩(traps)**을 정의한 객체. 다양한 트랩을 통해 원하는 동작을 추가하거나 수정할 수 있음.
const target = {
message: "Hello, Proxy!"
};
const handler = {
get: (target, property) => {
return property in target ? target[property] : "Property not found!";
}
};
const proxy = new Proxy(target, handler);
console.log(proxy.message); // "Hello, Proxy!"
console.log(proxy.nonexistent); // "Property not found!"
- target: Proxy가 감시할 대상 객체.
- handler: get 트랩을 사용하여 프로퍼티 접근을 가로채고, 존재하지 않는 프로퍼티에 대한 커스텀 동작을 정의함.
- proxy: 타겟 객체의 동작을 제어하는 프록시 객체.
2. Proxy 핸들러의 트랩
**핸들러(handler)**에는 여러 **트랩(trap)**이 정의될 수 있으며, Proxy 객체는 다양한 객체 동작을 가로채서 처리할 수 있음. 다음은 자주 사용되는 몇 가지 트랩임.
(1) get 트랩
- 객체의 프로퍼티에 접근할 때 동작을 가로챔.
const handler = {
get: (target, property) => {
return property in target ? target[property] : "Property not found!";
}
};
const proxy = new Proxy({ name: "Jerry" }, handler);
console.log(proxy.name); // "Jerry"
console.log(proxy.age); // "Property not found!"
- get 트랩은 객체의 프로퍼티를 접근할 때 특정 로직을 적용할 수 있게 해줌.
(2) set 트랩
- 객체의 프로퍼티에 값을 할당할 때 동작을 가로챔.
const handler = {
set: (target, property, value) => {
if (typeof value === "number") {
target[property] = value; // 값이 숫자일 때만 할당 허용
return true;
} else {
console.log("Invalid value type, only numbers are allowed.");
return false;
}
}
};
const proxy = new Proxy({}, handler);
proxy.age = 30; // 정상 작동
proxy.age = "thirty"; // "Invalid value type, only numbers are allowed."
- set 트랩은 값의 타입을 검사하거나, 값 할당을 제어할 때 유용하게 사용할 수 있음.
(3) has 트랩
- in 연산자를 사용할 때 동작을 가로챔.
const handler = {
has: (target, property) => {
if (property === "secret") {
return false; // "secret" 프로퍼티는 항상 숨김
}
return property in target;
}
};
const proxy = new Proxy({ message: "Hello" }, handler);
console.log("message" in proxy); // true
console.log("secret" in proxy); // false
- has 트랩은 객체에서 특정 프로퍼티를 숨기거나 커스텀 조건을 추가할 때 유용함.
(4) deleteProperty 트랩
- delete 연산자를 사용할 때 동작을 가로챔.
const handler = {
deleteProperty: (target, property) => {
if (property in target) {
delete target[property];
console.log(`${property} has been deleted.`);
return true;
}
return false;
}
};
const proxy = new Proxy({ name: "Jerry" }, handler);
delete proxy.name; // "name has been deleted."
- deleteProperty 트랩은 프로퍼티가 삭제될 때 동작을 가로채 커스텀 동작을 정의할 수 있음.
3. Proxy 활용 예시
(1) 데이터 유효성 검사
Proxy를 이용해 객체의 값을 할당할 때 유효성 검사를 수행할 수 있음.
const validator = {
set: function(target, property, value) {
if (property === "age" && typeof value !== "number") {
throw new TypeError("Age must be a number.");
}
target[property] = value;
return true;
}
};
const person = new Proxy({}, validator);
person.age = 25; // 정상 동작
person.age = "twenty-five"; // 오류 발생: "Age must be a number."
- set 트랩을 통해 객체의 프로퍼티에 값을 할당할 때, 유효성 검사를 수행하고 잘못된 값에 대해 오류를 발생시킬 수 있음.
(2) 자동 계산 필드
프록시를 사용하면 객체의 프로퍼티에 접근할 때 자동으로 계산된 값을 제공할 수 있음.
const product = {
price: 100,
quantity: 2
};
const handler = {
get: function(target, property) {
if (property === "total") {
return target.price * target.quantity; // price * quantity 계산 후 반환
}
return target[property];
}
};
const proxy = new Proxy(product, handler);
console.log(proxy.total); // 200
- get 트랩을 사용하여 total 프로퍼티에 접근할 때 자동으로 계산된 값을 반환할 수 있음.
(3) 로깅 및 디버깅
Proxy를 사용해 객체의 모든 동작을 감시하고, 값이 변경되거나 접근될 때 로그를 남길 수 있음
const person = {
name: "Jerry",
age: 25
};
const handler = {
get: function(target, property) {
console.log(`Getting property ${property}`);
return target[property];
},
set: function(target, property, value) {
console.log(`Setting property ${property} to ${value}`);
target[property] = value;
return true;
}
};
const proxy = new Proxy(person, handler);
proxy.name; // "Getting property name"
proxy.age = 30; // "Setting property age to 30"
- 이 예시는 객체의 모든 프로퍼티 접근 및 수정에 대해 로그를 출력하여, 디버깅에 도움을 줄 수 있음.
4. Proxy와 Reflect
Reflect 객체는 Proxy와 함께 자주 사용되며, 객체의 기본 동작을 안전하게 수행할 수 있는 메서드를 제공함. Proxy로 기본 동작을 가로채더라도, 원래의 객체 동작을 그대로 수행하고 싶을 때 **Reflect**를 사용함.
const handler = {
set: function(target, property, value) {
console.log(`Setting ${property} to ${value}`);
return Reflect.set(target, property, value); // 기본 동작 수행
}
};
const proxy = new Proxy({}, handler);
proxy.name = "Jerry"; // "Setting name to Jerry"
**Reflect.set**은 Proxy 내에서 기본적인 값 할당 동작을 그대로 수행하면서, 커스텀 로직도 추가할 수 있게 해줌.
5. Proxy의 사용 시기
Proxy는 다음과 같은 상황에서 매우 유용함:
- 데이터 유효성 검사: 객체에 값을 할당할 때 유효성 검사를 수행할 수 있음.
- 자동 값 계산: 특정 프로퍼티에 접근할 때 자동으로 계산된 값을 제공할 수 있음.
- 로깅 및 디버깅: 객체의 동작을 감시하고, 로그를 남겨 디버깅할 수 있음.
- 동적 API 생성: 객체의 프로퍼티가 동적으로 생성되거나 변경될 때 커스텀 동작을 추가할 수 있음.
요약:
- Proxy는 객체의 동작을 가로채서 커스텀 동작을 정의할 수 있는 강력한 도구임.
- **트랩(trap)**을 통해 프로퍼티 접근, 값 할당, 삭제, 함수 호출 등을 제어할 수 있음.
- Reflect와 함께 사용하면 객체의 기본 동작을 안전하게 수행하면서도 커스텀 동작을 추가할 수 있음.
- 유효성 검사, 로깅, 자동 값 계산 등 다양한 용도로 활용 가능.
728x90
반응형
'Web Development' 카테고리의 다른 글
[콜럼Vue스] Vue인스턴스 (0) | 2024.10.04 |
---|---|
[콜럼Vue스] Dynamic Arguments (2) | 2024.10.03 |
[콜럼Vue스] 전개연산자 (1) | 2024.10.01 |
[콜럼Vue스] promise (1) | 2024.10.01 |
[콜럼Vue스] 리터럴 Literal (1) | 2024.09.30 |