시냅스

TIL : JavaScript { Proxy } 본문

JavaScript

TIL : JavaScript { Proxy }

ted k 2021. 12. 3. 20:50

Proxy

 

Proxy - JavaScript | MDN

Proxy 객체는 기본적인 동작(속성 접근, 할당, 순회, 열거, 함수 호출 등)의 새로운 행동을 정의할 때 사용합니다.

developer.mozilla.org

 

immer나 state의 불변성 유지를 위해 알아보았다.

 

기본적인 동작 ( 속성 접근, 할당, 순회, 열거, 함수 호출 등)의 새로운 행동을 정의할 때 사용한다.

 

선언

new Proxy(target, handler);

 

예제

var handler = {
    get: function(target, name){
        return name in target?
            target[name] :
            37;
    }
};

var p = new Proxy({}, handler);
p.a = 1;
p.b = undefined;

console.log(p.a, p.b); // 1, undefined
console.log('c' in p, p.c); // false, 37

프로퍼티 이름이 객체에 없을 때, 기본값을 숫자 37로 리턴 받는 예제다.

handler 내부에 getter를 셋팅하고, p라는 객체에 프로퍼티는 name으로 받아 판단한다.

 

let validator = {
  set: function(obj, prop, value) {
    if (prop === 'age') {
      if (!Number.isInteger(value)) {
        throw new TypeError('The age is not an integer');
      }
      if (value > 200) {
        throw new RangeError('The age seems invalid');
      }
    }

    // The default behavior to store the value
    obj[prop] = value;
  }
};

let person = new Proxy({}, validator);

person.age = 100;
console.log(person.age); // 100
person.age = 'young'; // Throws an exception
person.age = 300; // Throws an exception

 

검증을 통해 set 해줄 수 있게 할 수도 있다.

 

let view = new Proxy({
  selected: null
},
{
  set: function(obj, prop, newval) {
    let oldval = obj[prop];

    if (prop === 'selected') {
      if (oldval) {
        oldval.setAttribute('aria-selected', 'false');
      }
      if (newval) {
        newval.setAttribute('aria-selected', 'true');
      }
    }

    // The default behavior to store the value
    obj[prop] = newval;
  }
});

let i1 = view.selected = document.getElementById('item-1');
console.log(i1.getAttribute('aria-selected')); // 'true'

let i2 = view.selected = document.getElementById('item-2');
console.log(i1.getAttribute('aria-selected')); // 'false'
console.log(i2.getAttribute('aria-selected')); // 'true'

위처럼 클래스에 대한 동적할당도 해줄 수 있는데,

toggle과 연관지어 생각해봄직 하다.

 

let products = new Proxy({
  browsers: ['Internet Explorer', 'Netscape']
},
{
  get: function(obj, prop) {
    // An extra property
    if (prop === 'latestBrowser') {
      return obj.browsers[obj.browsers.length - 1];
    }

    // The default behavior to return the value
    return obj[prop];
  },
  set: function(obj, prop, value) {
    // An extra property
    if (prop === 'latestBrowser') {
      obj.browsers.push(value);
      return;
    }

    // Convert the value if it is not an array
    if (typeof value === 'string') {
      value = [value];
    }

    // The default behavior to store the value
    obj[prop] = value;
  }
});

console.log(products.browsers); // ['Internet Explorer', 'Netscape']
products.browsers = 'Firefox'; // pass a string (by mistake)
console.log(products.browsers); // ['Firefox'] <- no problem, the value is an array

products.latestBrowser = 'Chrome';
console.log(products.browsers); // ['Firefox', 'Chrome']
console.log(products.latestBrowser); // 'Chrome'

위의 예제에서 처럼 어떤 특정한 프로퍼티를 추가해주거나 정정할 수 있는데

react 에서 쓰는 state에 연관지어 생각해봄직 하다.

'JavaScript' 카테고리의 다른 글

UUID 사용법  (0) 2021.11.27
TIL : JavaScript { Generator }  (0) 2021.11.06
TIL : JavaScript { Symbol, Class }  (0) 2021.11.05
TIL : JavaScript { this, arrowFunction, spread syntax }  (0) 2021.11.03
Comments