# Proxy (프록시)
Vue가 아닌 JavaScript의 내장기능인 '프록시'에 대해 알아보자.
let message = 'Hello!';
let longMessage = message + ' World!';
console.log(longMessage); //'Hello! World!'
message = 'Hello!!!!'; // message 값을 변경.
console.log(longMessage) // 'Hello! World!'. 값이 바뀌지 않았다.
위의 코드를 보면, message의 값을 변경하더라도 longMessage의 값이 바뀌지 않았다.
그 이유는 기본적으로 JavaScript는 반응형이 아니기 때문.
반응형은 Vue가 추가한 기능이다.
변수가 있고, 이후 해당 변수에 변경사항이 생긴다고 해도 앞서 작성한 연산이 재실행되지 않는다.
JavaScript가 message의 변경사항을 반영하지 않는다.
let longMessage = message + ' World!';
이렇게 JavaScript와 Vue의 작동원리에는 차이가 있다.
Vue는 내장 메커니즘을 통해 message의 변경사항을 인식하고, Vue앱에서 해당 message와 관련이 있는 부분을 업데이트한다. 이 작업에서 '프록시'를 사용한다.
## 프록시가 어떻게 작동하는가?
JavaScript 객체(아래 코드에서 data객체) 를 생성해보자. 그리고 그 객체(data)를 new Proxy를 통해 JavaScript 프록시로 래핑(첫번째 인수)한다.
(모던 JS에 내장된 생성자 함수이다. 따라서 이 코드를 테스팅할 때는 Chrome과 같은 모던 브라우저에서 작업해야한다.)
const data = {
message: 'Hello!',
};
const proxy = new Proxy(data);
하지만 여기에 더해서 두 번째 인수가 될 두 번째 객체도 입력해야한다.
래핑된 객체에 대한 handler를 담고 있는 객체여야 한다.
handler라는 객체부터 생성해보자.
## handler 객체
이 객체에는 특정 기능을 사용할 수 있는데, 프록시가 지원하는 일명 '트랩'을 설정할 수 있다.
예시로 set 트랩을 설정해보자.
const data = {
message: 'Hello!',
};
const handler = {
set(target, key, value) {
console.log('target', target);
console.log('key', key);
console.log('value', value);
}
}
const proxy = new Proxy(data, handler);
handler 내에 set함수를 추가하면, 자동으로 그 인수로서 target, key, value를 전송받는다.
생성한 handler 객체를 proxy의 두 번째 인수로 입력하자.
Proxy는 data객체를 첫 번째 인수로서 래핑한다. 따라서 상수 proxy를 통해 message에 액세스 할 수 있다.
new Proxy로 생성한 Proxy 객체가 message 프로퍼티를 갖기 때문에, 이에 따라 Proxy가 래핑하는 data 객체의 meesage에 상수 proxy도 액세스 할 수 있다.
proxy.message를 'Hello!!!'로 설정한 후, console.log로 target, key, value를 각각 확인해보자.
const data = {
message: 'Hello!',
};
const handler = {
set(target, key, value){
console.log('target', target),
console.log('key', key),
console.log('value', value),
}
};
const proxy = new Proxy(data, handler);
proxy.message = 'Hello!!!'; //proxy에 새로운 프로퍼티 설정
- target : 래핑된 객체가 출력.
- key : 새로운 값을 설정한 프로퍼티, 즉 message 출력
- value : 새로 설정한 값인 'Hello!!!' 출력
이렇게 setter 함수는 proxy에 새로운 프로퍼티가 설정될 때마다 트리거된다.
이를 통해 새 값이 설정된 프로퍼티가 무엇인지, new value는 무엇인지, 래핑된 원본 객체는 무엇인지 알 수 있다.
다른 프로퍼티(longMessage)를 하나 더 추가해보자.
const data = {
message: 'Hello!',
longMessage: 'Hello! World!',
}
const handler = {
set(target, key, value) {
if(key === 'message') { // key가 message인 경우.
target.longMessage = value + ' World!'; //message가 변경되면 longMessage도 바뀌어야한다.
}
target.message = value; //message 프로퍼티 자체도 설정해야한다.
}
};
const proxy = new Proxy(data, handler);
proxy.message = 'Hello!!!';
흥미로운 점을 하나 볼 수 있다.
console.log(proxy.longMessage)를 실행하면, message가 변경되면서 longMessage에도 변경사항이 반영된 것을 볼 수 있다.
즉, message 변경으로 longMessage가 업데이트 된 것.
이것으로 자체적인 반응형 시스템을 구축한 셈이다.
message 프로퍼티 하나를 추적할 때, 다른 프로퍼티도 message의 변경사항에 따라 업데이트되도록 하는 것.
간단한 예시였지만 정리하자면, 바로 이러한 반응형 작업을 Vue가 내부적으로 한다.
모든 data 프로퍼티를 추적하고, data 프로퍼티에 변경사항이 발생하면 Vue앱에서 해당 프로퍼티가 사용된 부분을 업데이트한다.
ex: 아래와 같이 messge 프로퍼티가 있는 부분을 업데이트해야한다고 Vue는 인식한다.
<p>{{ message }}</p>
프록시를 통해 프로퍼티를 래핑함으로써 새 값을 설정할 때 변경사항을 찾을 수 있다. 이것이 바로 Vue의 작동원리.
물론 Vue는 위의 JavaScript 코드로 나타낸 것 보다 훨씬 더 복잡한 과정을 거친다. computed 프로퍼티도 있고, 프로퍼티가 변경될 경우 트리거되는 watcher도 있으니깐.
** 출처: 모든 내용은 Udemy Vue-완벽가이드 강의를 기반으로 작성하였습니다.
'Vue.js' 카테고리의 다른 글
[Udemy Vue 완벽가이드 Section5] 63. 템플릿 이해하기 (0) | 2023.08.15 |
---|---|
[Udemy Vue 완벽가이드 Section5] 62. 하나의 앱 vs 여러 앱 (0) | 2023.08.15 |
[Udemy Vue 완벽가이드 Section5] 60. Vue의 반응성 소개 (0) | 2023.08.14 |
[Udemy Vue 완벽가이드 Section3] 48. 섹션 요약 (0) | 2023.08.14 |
[Udemy Vue 완벽가이드 Section3] 47. 목록 및 키 (key속성) (0) | 2023.07.26 |