본문 바로가기

프로그래밍/JavaScript

JavaScript_Proxy 객체

Proxy 객체

: Proxy 객체를 사용하면 한 객체에 대한 기본 작업을 가로채어 다른 동작을 할 수 있게 재정의하여 사용할 수 있다.
 
 
 
두 개의 메서드를 사용하여 생성한다.
 

1. target : Proxy의 대상이 되는 객체
2. handler : 가로채는 작업과 가로채는 작업을 재정의하는 객체

 
 
 

handler로 가로챌 수 있는 동작

핸들러 메서드작동 시점
get프로퍼티를 읽을 때
set프로퍼티에 값을 쓸 때
hasin 연산자가 작동할 때
deletePropertydelete 연산자가 작동할 때
apply함수를 호출할 때
constructornew 연산자가 작동할 때
getPrototypeOfObject.getPrototypeOf
setPrototypeOfObject.setPrototypeOf
isExtensibleObject.isExtensible
preventExtensionsObject.preventExtensions
getOwnPropertyDescriptorObject.getOwnPropertyDescriptor
ownKeysObject.getOwnPropertyNames
Object.getOwnPropertySymbols

 
 
 

속성이 없는 핸들러 

const target = {
    message1 : "힘껏",
    message2 : "웃자",
    message3 : "음하하"
};

const handler1 = {}; // 속성이 없는 핸들러

const proxy1 = new Proxy(target, handler1);


console.log(proxy1.message1); // 힘껏
console.log(proxy1.message2); // 웃자
console.log(proxy1.message3); // 음하하

→ 핸들러가 비어 있기 때문에 중간에 가로채는 트랩이 없으니 기본 메서드가 작동됨
 
 
 

get() 트랩 - property를 읽음

const target = {
    name : "박수",
    message : "짝짝"
};

const handler2 = {
    get(target, prop, receiver) { // prop : property 이름, receiver : get이 호출될 때 this (자기 자신)
        return `${prop} ${target[prop]}`;
    }
};

const proxy2 = new Proxy(target, handler2);

console.log(proxy2.name); // name 박수
console.log(proxy2.message); // message 짝짝

proxy2.age = "값 할당된 것이 출력 ~";
console.log(proxy2.age); // 값 할당된 것이 출력 ~

→ get()은 모든 속성 접근자를 재정의함
 
 
 

set() 트랩 - property에 값을 씀

const validator = { // handler3이라는 이름 대신 사용함
    set(obj, prop, value) { 
        if(prop === "age") {
            if(!Number.isInteger(value)) {
                throw new TypeError("나이가 숫자형이 아닙니다.");
            }
            if(value > 200) {
                throw new RangeError("나이 범위가 유효하지 않습니다.");
            }
        }
        
        obj[prop] = value;
        
        return true; // 성공
    }
};

const person = new Proxy({}, validator);
person.age = 100;

console.log(person.age); // 100
person.age = "asdf"; // TypeError 예외 발생
person.age = 201; // RangeError 예외 발생

→ 객체에 전달된 값을 확인하여 유효성 검사를 할 수 있음