πŸ“¦ μž‘λ™μ‚¬λ‹ˆ

ν•˜λ‚˜μ˜ ν‚€μ›Œλ“œλ₯Ό 작고 μ’€ νŽΈν•˜κ²Œ μ •λ¦¬ν•˜κ³  μ‹Άμ–΄ λ§Œλ“  μž‘λ™μ‚¬λ‹ˆ

μž‘λ™μ‚¬λ‹ˆλŠ” μ‘°μ„  ν›„κΈ° ν•™μž μ•ˆμ •λ³΅μ΄ νŽΈμ°¬ν•œ μž‘λ™μ‚°μ΄(ι›œεŒζ•£η•°)μ—μ„œ 유래된 말이닀.
μž‘λ™μ‚°μ΄λŠ” 작기(ι›œθ¨˜)의 ν˜•νƒœλ₯Ό 빌렀온 μ±…μœΌλ‘œ ꡬ체적인 체계가 μž‘ν˜€μžˆμ§€ μ•Šμ€ ν˜•μ‹μ΄λ‹€.
ν•­λͺ©μ΄ λ‹€μ†Œ λ‚œμž‘ν•˜κ³  λ‚΄μš©μ˜ ꡬ뢄이 ν˜Όλ™λ˜μ–΄μžˆλ‹€κ³  ν•œλ‹€. 🀣

πŸ—‚οΈ μž‘μ„±ν•˜κ²Œ 된 이유

바닐라 JS둜 κ°„λ‹¨ν•œ κΈ°λŠ₯을 κ΅¬ν˜„ν•˜λ‹€κ°€ Proxy 객체λ₯Ό μ•Œκ²Œ λ˜μ—ˆλ‹€. 이전에도 살짝 κ³΅λΆ€λŠ” ν–ˆμ—ˆμ§€λ§Œ, κ°œλ…μ€ 기얡이 λ‚˜λ„ 객체 자체의 μ‚¬μš©λ°©λ²•μ€ 기얡이 λ‚˜μ§ˆ μ•Šμ•„μ„œ μ •λ¦¬ν•˜κ²Œ λ˜μ—ˆλ‹€.

πŸ—‚οΈ Proxy

ProxyλŠ” 주둜 λŒ€λ¦¬ν•˜λ‹€., κ°€λ‘œμ±„λ‹€., ν›”μΉ˜λ‹€. λ“±μ˜ 의미λ₯Ό κ°–λŠ”λ‹€. ν”νžˆ μš°λ¦¬κ°€ μ˜λ½μ§€λΌκ³  λΆ€λ₯΄λŠ” 슀파이 λŠλ‚Œμ˜ 단어도 Proxyμ—μ„œ 유래된 것이닀.

IT μš©μ–΄λ‘œ Proxy(ν”„λ‘μ‹œ)κ°€ μ‚¬μš©λ˜λŠ” λ‹€μ–‘ν•­ 상황이 μžˆλ‹€. μš°μ„  Proxy μ„œλ²„λΌκ³  ν•˜λ©΄ λŒ€λ¦¬ μ„œλ²„λΌκ³  μƒκ°ν•˜λ©΄ λœλ‹€. ν΄λΌμ΄μ–ΈνŠΈκ°€ μ„œλ²„μ— μš”μ²­μ„ 보내면 Proxy μ„œλ²„κ°€ μš”μ²­μ„ λ°›μ•„μ„œ μ„œλ²„μ— μš”μ²­μ„ 보내고, μ„œλ²„κ°€ 응닡을 보내면 Proxy μ„œλ²„κ°€ 응닡을 λ°›μ•„μ„œ ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ 응닡을 λ³΄λ‚΄λŠ” 방식이닀. μ΄λ ‡κ²Œ Proxy μ„œλ²„λ₯Ό λ‘λŠ” μ΄μœ λŠ” μ—¬λŸ¬κ°€μ§€κ°€ μžˆμ§€λ§Œ, 주둜 λ³΄μ•ˆκ³Ό μ„±λŠ₯을 μœ„ν•΄ μ‚¬μš©ν•œλ‹€.

κ·Έλ ‡λ‹€λ©΄ JSμ—μ„œμ˜ ProxyλŠ” μ–΄λ–€ 역할을 할지 μ•Œμ•„λ³΄μž!

πŸ—‚οΈ Proxy in JS

JSμ—μ„œμ˜ ProxyλŠ” 객체의 기본적인 λ™μž‘(JS의 κ°μ²΄μ—μ„œ 값을 μ½μ–΄μ˜€λŠ” 것은 get, 값을 λ³€κ²½ν•˜λŠ” 것은 set이라고 ν•œλ‹€.)을 κ°€λ‘œμ±„μ„œ λ‹€λ₯Έ λ™μž‘μ„ ν•  수 있게 ν•΄μ€€λ‹€. 이λ₯Ό 톡해 객체의 λ™μž‘μ„ μˆ˜μ •ν•˜κ±°λ‚˜, 객체에 μ ‘κ·Όν•˜λŠ” 방식을 λ³€κ²½ν•  수 μžˆλ‹€.

μ•„λž˜μ™€ 같은 상황을 κ°€μ •ν•΄λ³΄μž.

const target = { name: 'jayden' };

target.name; // jayden

μ•Œλ‹€μ‹œν”Ό target.name으둜 name ν”„λ‘œνΌν‹°μ˜ 값을 getν•  수 μžˆλ‹€. 그런데 μ—¬κΈ°μ„œ λ§Œμ•½μ— 이 값을 μ½μ–΄μ˜¬ λ•Œ, μ–΄λ–€ 무언가λ₯Ό μΆ”κ°€μ μœΌλ‘œ μž‘μ—…ν•΄μ£Όκ³  μ‹Άλ‹€λ©΄ μ–΄λ–»κ²Œ ν•΄μ•Όν• κΉŒ..? Proxyλ₯Ό μ•Œμ§€ λͺ»ν•œλ‹€λ©΄ μ•„λž˜μ™€ 같이 μ½”λ“œλ₯Ό μž‘μ„±ν•  수 μžˆμ„ 것이닀.

const target = { name: 'jayden' };

const doSomething = (target, callback) => {
  const result = target.name;
  callback(result);
  return result;
};

doSomething(target, (result) => {
  console.log(result); // jayden
});

doSomething에 targetκ³Ό μ–΄λ–€ μ½œλ°±μ„ μ „λ‹¬ν•˜μ—¬ name에 ν•΄λŒ•ν•˜λŠ” 값을 λ°˜ν™˜ν•¨κ³Ό λ™μ‹œμ— ν•΄λ‹Ή 값을 log둜 μ°λŠ” ν–‰μœ„λ₯Ό ν•  수 μžˆλ‹€. 이제 Proxyλ₯Ό μ‚¬μš©ν•΄λ³΄μž.

const target = { name: 'jayden' };
const handleTarget = {
  get(target, prop, receiver) {
    console.log({ target, prop, receiver });
    return target[prop]; // μ΄λ ‡κ²Œ λ°˜ν™˜ν•˜λŠ” 게 기본적인 getter λ™μž‘
  },
  set(target, prop, newValue) {
    console.log({ target, prop, newValue });
    target[prop] = newValue; // 이게 setter의 κΈ°λ³Έ λ™μž‘
  },
};

const proxyObj = new Proxy(target, handleTarget);

Proxy 객체에 targetκ³Ό handlerλ₯Ό μ „λ‹¬ν•˜λ©΄, handler에 μ •μ˜λœ λ™μž‘μ„ μˆ˜ν–‰ν•˜κ²Œ λœλ‹€. μœ„μ˜ μ½”λ“œμ—μ„œλŠ” getκ³Ό set을 μ •μ˜ν–ˆκΈ° λ•Œλ¬Έμ— target의 값을 μ½μ–΄μ˜€κ±°λ‚˜ λ³€κ²½ν•  λ•Œ, handler에 μ •μ˜λœ λ™μž‘μ„ μˆ˜ν–‰ν•˜κ²Œ λ˜λŠ” 것이닀.

처음 보면 λ³΅μž‘ν•΄λ³΄μ΄μ§€λ§Œ μ½”λ“œλ₯Ό ν•œ 번 μž‘μ„±ν•΄λ³΄λ©΄ 생각보닀 κ°„λ‹¨ν•œ 것을 μ•Œ 수 μžˆλ‹€.

ProxyλΌλŠ” 객체가 μžˆμŒμ„ κΈ°μ–΅ν•˜κ³  μ½”λ“œλ₯Ό μž‘μ„±ν•˜λ‹€κ°€ ν•„μš”ν•œ 상황이 생기면 Proxyλ₯Ό μ‚¬μš©ν•΄λ³΄μž!