대상 객체에 대한 상호 작용 가로채기 및 제어
Proxy 객체를 사용하면 특정 객체와의 상호 작용을 더 잘 제어할 수 있습니다.
Proxy 객체는 객체와 상호 작용할 때마다 동작을 결정할 수 있습니다. 예를 들어 값을 가져오거나 값을 설정할 때입니다.
일반적으로 Proxy는 다른 사람의 대역을 의미합니다. 그 사람에게 직접 말하는 대신, 당신이 연락하려고 했던 사람을 대리할 대리인과 이야기하게 될 것입니다. JavaScript에서도 동일한 일이 발생합니다. 대상 객체와 직접 상호 작용하는 대신 Proxy 객체와 상호 작용합니다.
John Doe를 나타내는 person 개체를 만들어 보겠습니다.
const person = {
name: "John Doe",
age: 42,
nationality: "American"
};
이 객체와 직접 상호 작용하는 대신 Proxy 객체와 상호 작용하기를 원합니다. JavaScript에서는 Proxy의 새 인스턴스를 만들어 새 proxy를 쉽게 만들 수 있습니다.
const person = {
name: "John Doe",
age: 42,
nationality: "American"
};
const personProxy = new Proxy(person, {});
Proxy의 두 번째 인수는 handler를 나타내는 객체입니다. handler 객체에서 상호 작용 유형에 따라 특정 동작을 정의할 수 있습니다.
Proxy handler에 추가할 수 있는 많은 방법이 있지만 가장 일반적인 두 가지 방법은 get 및 set입니다.
효과적으로, 일어날 일은 다음과 같습니다:
person 객체와 직접 상호 작용하는 대신 personProxy와 상호 작용합니다.
personProxy에 handler를 추가해 보겠습니다. 속성을 수정하려고 Proxy에서 set 메서드를 호출할 때 Proxy가 속성의 이전 값과 새 값을 기록하기를 원합니다. 속성에 액세스하려고 할 때 Proxy에서 get 메서드를 호출하면 Proxy가 속성의 키와 값을 포함하는 더 읽기 쉬운 문장을 log로 나타내길 원합니다.
const personProxy = new Proxy(person, {
get: (obj, prop) => {
console.log(`The value of ${prop} is ${obj[prop]}`);
},
set: (obj, prop, value) => {
console.log(`Changed ${prop} from ${obj[prop]} to ${value}`);
obj[prop] = value;
}
});
좋습니다! 속성을 수정하거나 검색하려고 할 때 어떤 일이 발생하는지 봅시다.
// index.js
const person = {
name: "John Doe",
age: 42,
nationality: "American"
};
const personProxy = new Proxy(person, {
get: (obj, prop) => {
console.log(`The value of ${prop} is ${obj[prop]}`);
},
set: (obj, prop, value) => {
console.log(`Changed ${prop} from ${obj[prop]} to ${value}`);
obj[prop] = value;
return true;
}
});
personProxy.name;
personProxy.age = 43;
name 속성에 액세스할 때 Proxy는 더 보기 편한 문장을 반환했습니다. name 값은 John Doe입니다.
age 속성을 수정할 때 Proxy는 이 속성의 이전 값과 새 값을 반환했습니다. 나이가 42에서 43으로 변경되었습니다.
Proxy는 유효성 검사를 추가하는 데 유용할 수 있습니다. 사용자는 사람의 나이를 문자열 값으로 변경하거나 빈 이름을 지정할 수 없어야 합니다. 또는 사용자가 존재하지 않는 객체의 속성에 액세스하려는 경우 사용자에게 알려야 합니다.
const personProxy = new Proxy(person, {
get: (obj, prop) => {
if (!obj[prop]) {
console.log(
`Hmm.. this property doesn't seem to exist on the target object`
);
} else {
console.log(`The value of ${prop} is ${obj[prop]}`);
}
},
set: (obj, prop, value) => {
if (prop === "age" && typeof value !== "number") {
console.log(`Sorry, you can only pass numeric values for age.`);
} else if (prop === "name" && value.length < 2) {
console.log(`You need to provide a valid name.`);
} else {
console.log(`Changed ${prop} from ${obj[prop]} to ${value}.`);
obj[prop] = value;
}
}
});
잘못된 값을 전달하려고 할 때 어떤 일이 발생하는지 봅시다!
// index.js
const person = {
name: "John Doe",
age: 42,
nationality: "American"
};
const personProxy = new Proxy(person, {
get: (obj, prop) => {
if (!obj[prop]) {
console.log(`Hmm.. this property doesn't seem to exist`);
} else {
console.log(`The value of ${prop} is ${obj[prop]}`);
}
},
set: (obj, prop, value) => {
if (prop === "age" && typeof value !== "number") {
console.log(`Sorry, you can only pass numeric values for age.`);
} else if (prop === "name" && value.length < 2) {
console.log(`You need to provide a valid name.`);
} else {
console.log(`Changed ${prop} from ${obj[prop]} to ${value}.`);
obj[prop] = value;
}
return true;
}
});
personProxy.nonExistentProperty;
personProxy.age = "44";
personProxy.name = "";
프록시는 잘못된 값으로 person 개체를 수정하지 않았는지 확인하여 데이터를 순수하게 유지하는데 도움이 됩니다!
javaScript는 Reflect 라는 내장 객체를 제공하므로 프록시로 작업할 때 대상 객체를 더 쉽게 조작할 수 있습니다.
이전에는 대괄호 표기법으로 값을 직접 가져오거나 설정하여 프록시 내에서 대상 개체의 속성을 수정하고 액세스하려고 했습니다. 대신 Reflect 객체를 사용할 수 있습니다. Reflect 객체의 메서드는 handler 객체의 메서드와 이름이 같습니다.
obj[prop]를 통해 속성에 액세스하거나 obj[prop] = value를 통해 속성을 설정하는 대신 Reflect.get() 및 Reflect.set()을 통해 대상 객체의 속성에 액세스하거나 수정할 수 있습니다.
const personProxy = new Proxy(person, {
get: (obj, prop) => {
console.log(`The value of ${prop} is ${Reflect.get(obj, prop)}`);
},
set: (obj, prop, value) => {
console.log(`Changed ${prop} from ${obj[prop]} to ${value}`);
Reflect.set(obj, prop, value);
}
});
Reflect 개체를 사용하여 대상 개체의 속성에 쉽게 액세스하고 수정할 수 있습니다.
// index.js
const person = {
name: "John Doe",
age: 42,
nationality: "American"
};
const personProxy = new Proxy(person, {
get: (obj, prop) => {
console.log(`The value of ${prop} is ${Reflect.get(obj, prop)}`);
},
set: (obj, prop, value) => {
console.log(`Changed ${prop} from ${obj[prop]} to ${value}`);
return Reflect.set(obj, prop, value);
}
});
personProxy.name;
personProxy.age = 43;
personProxy.name = "Jane Doe";
프록시는 개체의 동작에 대한 제어를 추가하는 강력한 방법입니다. 프록시는 다양한 사용 사례를 가질 수 있습니다. 유효성 검사, 형식 지정, 알림 또는 디버깅에 도움이 될 수 있습니다.
Proxy 개체를 과도하게 사용하거나 각 처리기 메서드 호출에 대해 과중한 작업을 수행하면 응용 프로그램 성능에 쉽게 부정적인 영향을 줄 수 있습니다. 성능이 중요한 코드에는 프록시를 사용하지 않는 것이 가장 좋습니다.