해당 포스트는
JavaScript
의Proxy
에 대한 얕은 이해를 바탕으로 간단한 사용법만 정리한 포스트입니다.
🫣 Proxy
지정한 객체의 지정한 동작을 대신 처리해주는 특수 객체입니다.
서버에서도 프록시 서버라고 해서 중간에 거쳐가는 서버를 만들기도 합니다.
https
를 적용하기 위해서 nginx
를 프록시 서버로 두고 실제 서버를 nginx
를 거쳐서만 접근할 수 있도록 만들기도 하죠.
brower
-> nginx
-> 실제 서버
-> nginx
-> brower
같은 동작을 통해 실제 서버
의 위치를 숨길 수 있는 기능도 있습니다.
어떤 객체의 프로퍼티들을 요청할 때마다 로그를 남기고 싶은 경우, 어떤 객체에 프로퍼티를 변경할 때 원하는 타입만 받고 싶은 경우 등에서 사용할 수 있습니다.
1. 동작 방식
- 특정 객체를 기준으로
Proxy
객체 생성 - 특정 객체에 어떤 동작을 하는 경우(숨겨진 내부 메서드 동작하는 경우)
Proxy
에서 가로챔 Proxy
에 명시된 동작의 경우 대신 처리하고 응답 / 그게 아니라면 원래 객체로 전달 후 원래 객체에서 처리 후 응답
2. 가로챌 수 있는 동작들
내부 메서드 | 핸들러 메서드 | 작동 시점 |
---|---|---|
[[Get]] | get | 프로퍼티 읽는 시점 |
[[Set]] | set | 프로퍼티 수정 시점 성공 여부에 따른 T /F 반환 필수 |
[[HasProperty]] | has | in |
[[Delete]] | deleteProperty | delete 성공 여부에 따른 T /F 반환 필수 |
[[Call]] | apply | 함수 호출 시점 |
[[Construct]] | construct | new |
[[GetPrototypeOf]] | getPrototypeOf | Object.getPrototypeOf |
[[SetPrototypeOf]] | setPrototypeOf | Object.setPrototypeOf |
[[IsExtensions]] | isExtensible | Object.isExtensible |
[[PreventExtensions]] | preventExtensions | Object.preventExtensions |
[[DefineOwnProperty]] | defineProperty | Object.defineProperty , Object.defineProperties |
[[GetOwnProperty]] | getOwnPropertyDescriptor | for~in , Object.keys/values/entries |
[[OwnPropertyKeys]] | ownKeys | for~in , Object.keys/values/entries |
3. 사용법
1
let proxy = new Proxy(target, handler)
target
: 타겟 객체handler
: 동작을 가로채는trap
이 담긴 객체
target
에 어떤 동작을 했을 경우, handler
에 해당 동작에 맞는 trap
이 있다면 가로채고 그게 아니라면 target
에서 원래 작업을 실행
4. 예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// get
const proxy = new Proxy(
{ name: "john", age: 26 },
{
get(target, prop, receiver) {
console.log("해당 key에 맞는 value 요청 >> ", prop, target[prop]);
return target[prop];
},
}
);
proxy.name;
proxy.age;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// set
const proxy = new Proxy(
{ name: "john", age: 26, length: 2 },
{
set(target, prop, value, receiver) {
if (prop === "length") return false;
Object.defineProperty(receiver, "length", { enumerable: false });
Reflect.set(target, prop, value, receiver);
target.length = Object.keys(receiver).length;
return true;
},
}
);
console.log(proxy.length); // 2
proxy.gender = true;
console.log(proxy.length); // 3
😶 마무리
아직 부족함이 많아서 지금 당장은 Proxy
로 무엇을 할 수 있을지는 감이 안 오네요.
하지만 잘 활용한다면 정말 많은 곳에서 좋은 방식으로 사용할 수 있을 거라는 느낌이 들고 Redux
에서 불변성 지키려고 사용하던 immer
에도 사용하고 있다고 하네요.
라이브러리를 갖다 쓰는 개발자보다 직접 라이브러리를 만드는 개발자들이 잘 활용할 거라는 느낌이 많이 들지만 알아두면 손해 볼 건 없으니 사용법 정도만 알아두고 나중에 필요하면 그때 공부해서 사용하고 활용법으로 작성해보겠습니다.