한 객체에 대한 기본 작업을 가로채고 재정의하는 프록시 객체 생성 가능
class나 Closures를 통해 객체를 설계할수 있지만, 이를 더 쉽게 설계하도록 도와줌
속성 액세스를 기록하고, 입력의 유효성을 검사하고, 형식을 지정하거나, 삭제하는 데 활용
일반적으로 직접 구현하지 않음
👉 Vue3의 반응성에 Proxy가 내부적으로 사용
get(target, prop, receiver): 속성에 접근할 때 호출
set(target, prop, value, receiver): 속성에 값을 설정할 때
has(target, prop): 속성이 있는지 확인할 때 (in 연산자)
deleteProperty(target, prop): 속성을 삭제할 때 호출 (delete 연산자).
ownKeys(target): 객체의 고유 속성 키를 나열할 때 호출
(Object.getOwnPropertyNames, Object.getOwnPropertySymbols)
apply(target, thisArg, args): 함수 객체를 호출할 때 호출
construct(target, args): 생성자 함수로서 호출할 때 호출 (new 연산자)
👩🏻💻예시 코드
// 기본 예제 let obj = { name: '홍길동', age: 20 } // Proxy 관리가 되는 객체 const handler = { get(obj, prop) { // return obj[prop]; // undefined가 출력돼서 ui상 오류가 노출 됨! return prop in obj ? obj[prop] : '없는 데이터!'; // null이면 '없는 데이터!' 출력된다. }, } const proxy = new Proxy(obj, handler); document.write(proxy.name + '<br>'); // 홍길동 document.write(proxy.name2 + '<br>'); // 없는 데이터! document.write(proxy.age + '<br>'); // 20 document.write(proxy.age2 + '<br>'); // 없는 데이터! // 복합 예제 - member 활용 const member = { memberId: 'testId1234', name: '홍길동', pId: '900514-1234567', age: 30, password: 'testpassword1234', } const handler2 = { // set의 경우는 입력값 제한을 걸수 있다. set(obj, prop, value) { if (prop === 'age') { if (!Number.isInteger(value)) { throw new TypeError('정수가 아닙니다.'); } if (value < 0 || value > 200) { throw new RangeError('나이 범위가 아닙니다.'); } } if (prop === 'password') { if (value.length < 4) { throw new Error('4글자 보다 적습니다.'); } } obj[prop] = value; }, // get은 외부로 데이터를 주지 않거나(private), 특정 처리가 필요할때 활용한다. get(obj, prop, receiver) { if (prop == 'password') { return '*'.repeat(obj['password'].length); } if (prop == 'pId') { return obj['pId'].substr(0, 8) + '*'.repeat(6); } if (prop in obj == false) { throw new Error('데이터가 없습니다.'); } // return obj[prop]; // Reflect 활용, 자동으로 get을 생성하여 전달된다. return Reflect.get(...arguments); } } const proxy2 = new Proxy(member, handler2); document.write(proxy2.memberId + '<br>'); document.write(proxy2.password + '<br>'); document.write(proxy2.name + '<br>'); document.write(proxy2.age + '<br>'); document.write(proxy2.pId + '<br>'); // document.write(proxy2.name2 + '<br>'); // 데이터가 없습니다. proxy2.age = 34; // proxy2.age = -10; // RangeError // proxy2.age = '10'; // TypeError document.write(proxy2.age + '<br>'); // proxy2.password = '123'; // Error proxy2.password = '1234'; document.write(proxy2.password + '<br>');