[고급 자바스크립트] 프록시 객체 사용법

프록시란 무엇인가?

ES6의 프록시(Proxy)는 객체의 변화를 감지해 특정 동작의 트랩(trap)을 설정할 때 사용할 수 있습니다. 데이터 검증에 사용하는 Validator로 사용할 수도 있고, 데이터 변화를 감지하는 로거(logger)로도 사용할 수 있습니다.

위의 코드를 보면 프록시는 2개의 매개변수를 사용합니다. 첫 번째는 프록시에 사용할 대상 객체이고 두 번째 매개변수는 핸들러로 setter와 getter 프로퍼티 및 핸들러 함수(또는 트랩)를 설정할 수 있습니다. 위의 코드에서 보면 프로퍼티에 값을 할당하는 과정(set 발생)이 발생할 때마다 위의 프록시 함수(propValidator)에 있는 setter 함수가 실행되며 값을 검증하게 됩니다.

저는 코드에서 name이라는 프로퍼티에 대해서 값을 검증하고 있는데 타입 에러와 레인지 에러를 검증합니다. 검증 과정에서 허용되지 않은 값이 들어오는 경우 에러를 리턴해 함수를 구성했습니다. 프록시의 매개변수에 대해 좀 더 살펴보면 다음과 같이 설명합니다. (프록시에 대한 MDN 문서)

프록시 MDN 문서 중 일부

프록시 객체에서 핸들러 부분을 잘 활용하면 원하지 않은 데이터가 들어왔을 때 검증 후 에러를 리턴할 뿐 아니라 데이터를 대체하는 용도로도 활용될 수 있습니다. 예를 들면 에러가 될 수 있는 특수문자나 파싱 과정에서 필요 없는 HTML 문자열 등을 제거하는 것도 가능할 것입니다.


프록시 활용하기

프록시를 제대로 활용하기 위해서는 어떤 트랩이 있는지 알고, 활용하는 연습이 필요합니다.

1) get 메서드

**프로퍼티가 존재하지 않는(undefined)경우일 때는 "한상훈"**이라는 제 이름이 나오고, 값이 존재할 때는 **값을 리턴(target[prop])**하는 코드입니다. 이 짧은 코드는 활용도가 다양합니다. 자바스크립트를 사용하다보면 값이 존재하지 않는 경우에 참조 에러가 발생하는 경우가 있습니다.

객체가 아닌 값(c)에 대해 선언되지 않은 프로퍼티(a)에 접근하려고 할 때 에러가 발생하는데, 에러가 캐칭되지 않는 경우 프론트와 백엔드 모든 분야에서 시스템이 멈추는 현상을 야기합니다. 하지만 위의 코드를 프록시를 사용해 감싸준다면, 존재하지 않는 프로퍼티에 대해 default값으로 설정한 "한상훈"이라는 문자열이 리턴되므로 에러로 인해 시스템이 멈추는 현상을 막을 수 있습니다.

2) has 메서드

이번엔 객체의 Private 프로퍼티를 감춰보도록 하겠습니다. 자바스크립트의 컨벤션(convention) 중 하나는 외부의 접근을 제한할 필요가 있는 변수 또는 프로퍼티에 대해 언더바(_)로 네이밍을 합니다. 아래의 코드는 언더바로 시작되는 프로퍼티에 대해서 존재하는지 검사할 때 언제나 false를 리턴하는 프록시 코드입니다.

출처: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global\_Objects/Proxy/Proxy/has

위의 코드에서 monster1이라는 객체에 할당된 _secret이라는 값은 존재하는지 프록시 없이 검사해보면 true를 리턴합니다.(마지막줄 콘솔로그) 반면 프록시를 사용해 monster1를 감싸주면 해당 프로퍼티의 존재 유무를 false로 리턴하여 외부의 요청에 대해 감출 수 있습니다. 데이터를 내부 로직에서만 사용하고, 외부에서 엑세스는 제한해야하는 경우에는 이와 같이 has를 사용해 값의 존재 유무를 감춰줄 수 있습니다.

3) set 메서드

앞선 아이디어를 조금 더 발전하면 특정 객체의 값이 존재하는지 확인을 막는 것 뿐만 아니라 재할당을 못하도록 제한할 수 있습니다.

위의 코드를 보면 언더바(_)로 시작하는 프로퍼티에 대해 할당이 이뤄질 때 값의 변화 없이 return으로 빠져나가 아무 일도 발생하지 않도록 처리하고 있습니다. 이렇게 set 메서드를 활용하면 값이 차후에 변경되어 문제가 발생하는 것을 막을 수 있습니다. 여기서 조금 더 나아가면 접근 불가능한 프로퍼티에 대해서는 에러를 리턴하도록 하는 처리도 가능할 것입니다.

4) isExtensible 메서드

앞선 코드에서는 값의 재할당을 방어하는 프록시 사용법을 살펴봤다면 객체의 확장(extend)을 막는 것도 알아봅시다.

위의 코드는 자바스크립트를 사용해 npm에 올릴 라이브러리를 제작해보신 적이 없으시면 거의 보기 힘든 메서드가 나옵니다. 바로 Object.preventExtensions입니다. 간단하게 객체의 확장을 방지하는 메서드입니다.

개발자들이 프로젝트를 진행할 때 사용하는 라이브러리나 유틸리티 함수들은 사용 과정에서 드물게 의도하진 않았지만 프로퍼티와 값을 할당하여 사용하는 경우도 생기곤 합니다. 이러한 휴먼에러를 막기 위해서 확장을 할 필요가 없는 객체에 대해서 확장을 막아주는 코드를 사용할 수 있는데, 위의 코드는 이 변화를 감지하는 예입니다.

위의 코드는 MDN에 있는 흔한 예제이지만 초보자 분들에게는 Reflect라는 게 무엇인지도 헷갈리실 것 같습니다. Reflect는 타겟 객체의 상태를 불린으로 리턴하는 여러 메서드를 가진 자바스크립트 기본 객체라고 보시면 됩니다.

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Reflect

[Reflect - JavaScript | MDN

Reflect는 중간에서 가로챌 수 있는 JavaScript 작업에 대한 메서드를 제공하는 내장 객체입니다. 메서드의 종류는 프록시 처리기와 동일합니다. Reflect는 함수 객체가 아니므로 생성자로 사용할 수

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global\_Objects/Reflect](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Reflect) 

Reflect의 처리기(메서드)가 프록시와 연동됩니다. Reflect의 메서드를 통해 검증하는 값은 프록시에서도 핸들러에 할당하여 처리할 수 있고, 이에 대한 불린 값은 Reflect를 통해 얻을 수 있습니다.

5) apply 메서드

apply는 객체가 함수일 때 사용하면 좋은 메서드입니다. 프록시에 apply를 사용하면 함수가 호출될 때마다 로그를 찍거나 우리가 원하는 어떠한 사전 동작도 코드상으로 구현해 둘 수 있습니다.

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global\_Objects/Proxy/Proxy/apply

p라는 프록시 객체는 빈 함수를 타겟으로 가지고 있습니다. p를 호출하게 되면 프록시에 할당된 콘솔로그 코드 및 리턴문이 실행되고 이후에 console.log 값이 호출되는 것을 볼 수 있습니다.

여기까지 따라오셨다면 프록시 객체를 하나의 유틸리티 함수로 만들어 사용하여 함수 전처리에 사용하거나 또는 객체를 보호하거나 확장하거나, 에러 캐칭을 하거나 예상치 못한 에러로 방어하는 아이디어를 떠올리실 수 있을 겁니다. 프록시는 코드의 완성도를 높히고, 검증, 보호, getter, setter 모두 활용될 수 있는 아이디어입니다. 꼭 활용해보세요.

Comments

    More from Howdy의 블로그

    See all posts

    특별한 법칙은 아니지만 자주 생각하려는 법칙이 있다. 향기의 법칙이라고 명명한 이 법칙은 무척이나 간단하다. 어떠한 상황에서든 상대를 유혹하라는 것이다. 원하는 것이 있다면 상대방이 원하도록 유혹하는 것이다. 이는 아주 간단한 원칙인데 동시에 매우 달성하기 어려운 법칙이기도 하다. 향…

    Sanghoon Han

    향기의 법칙

    Hearts 1Comments 110/07/2026

    하루가 멀다하고 사고가 터지는 것이 인간사. 인간이 만든 것 중 무엇이 대단하다 말할 수 있을까. 무엇이 완전하다 말할 수 있을까. 무엇이 영원하다 말할 수 있을까. 영원한 것은 단 하나도 없고 먼지가 쌓이지 않는 것도 단 하나도 없다. 기회 역시 영원하지 않아서 영원할 것 같은 젊음…

    Sanghoon Han

    영원하지 않다

    Hearts 0Comments 010/07/2026

    이카루스는 태양에 가까이 가면 안된다는 것을 알았으나 높게 날았다. 깃을 붙인 밀납이 녹아 깃이 떨어져 나가고 나서야 그는 자신의 미래를 보았다. 자유로 향하는 날개를 얻었을 때 태양을 향해서도 바다를 향해서도 안됐다. 고도를 유지하며, 섬세하게 바람을 타지 않는다면 어디로든 날아갈…

    Sanghoon Han

    자유의 날개

    Hearts 0Comments 010/07/2026

    인간이 보편적으로 누리는 권리는 대부분 거래를 통해 획득했다. 참정권은 군복무, 참전으로 얻었고, 링컨의 노예제 해방을 위해선 산업화된 사회에서의 흑인 인권이 필요했다. 반면 노예를 사용하는 것이 경제적 이득이 되는 남부군의 입장에서는 당시 기준으로 재산권 침해에 해당한다고 보았기에…

    Sanghoon Han

    민주주의 붕괴

    Hearts 0Comments 010/07/2026