๐Ÿ’ก ๋ฐ˜์‘ํ˜•๋ฐ์ดํ„ฐ ํŠน์ง• / Proxy / ๋ถˆ๋ณ€์„ฑ

23138 ๋‹จ์–ด ์ค‘์š”vuevue

๋ฐ˜์‘ํ˜•๋ฐ์ดํ„ฐ

๐Ÿง„ ๋ฐ˜์‘ํ˜•๋ฐ์ดํ„ฐ ํŠน์ง•

  1. ๋ฐ˜์‘ํ˜• ๋ฐ์ดํ„ฐ๋ฅผ ์ •์˜ ํ•  ๋•Œ๋Š” ๋ฏธ๋ฆฌ data ์˜ต์…˜์— ์„ ์–ธํ•˜์ง€์•Š์œผ๋ฉด ๋‚˜์ค‘์— ์ถ”๊ฐ€๋˜๋Š” ๋ฐ์ดํ„ฐ๋Š” ๋ฐ˜์‘์„ฑ์„ ๊ฐ€์ง€์ง€ ์•Š๋Š”๋‹ค.
  2. ๊ธฐ๋ณธ์ ์œผ๋กœ ๋งŒ๋“  data๊ฐ€ ๊ฐ€์ง„ ์˜ต์…˜์€ vm.key์™€ vm.$data.key์— ์กด์žฌํ•œ๋‹ค.
  3. ์›๋ž˜๋Š” vm.$data.key์— ๊ฐ’์ด ์„ ์–ธ์ด ๋˜์ง€๋งŒ this๋ฅผ ํ†ตํ•ด์„œ ์ ‘๊ทผ ํ•  ์ˆ˜ ์žˆ๋„๋ก vm.key๋„ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ค์—ˆ๋‹ค.
    (๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๋ฉด ๋‘˜๋‹ค ์„œ๋กœ๊ฐ„์˜ ์—ฐ๊ฒฐ๋กœ ์˜ํ–ฅ์„ ๋ฐ›๋Š”๋‹ค.)
<div id="app">
  <h1>{{count}}</h1>
  <h2>{{double}}</h2>
</div>
</body>
<script>
  const App = {
    data() {
      return {
        count: 0
      }
    }
  }
  const vm = Vue.createApp(App).mount('#app')
</script>


๋งŒ๋“ค์–ด์ง„ vm์˜ ๊ฒฝ์šฐ data์˜ต์…˜์„ ๋ฐ›๋Š” count๋Š”
vm.count์—๋„ ์กด์žฌํ•˜๊ณ  , vm.$data.count์—๋„ ์กด์žฌํ•œ๋‹ค.
์ฆ‰,๋ฐ˜์‘ํ˜• ๋ฐ์ดํ„ฐ ํŠน์ง• 2,3๋ฒˆ์ด ์„ฑ๋ฆฝํ•œ๋‹ค.


์ง์ ‘ $data.double๊ณผ double์˜ ๊ฐ’์„ ๋ฐ”๊พธ์–ด๋„ <h2>์— ์ €์žฅํ•œ double์ด ์ ์šฉ๋˜์ง€ ์•Š๋Š” ๊ฒƒ์„ ๋ณด๋ฉด ๋ฐ˜์‘ํ˜• ๋ฐ์ดํ„ฐ ํŠน์ง• 1๋ฒˆ์ด ์„ฑ๋ฆฝํ•œ๋‹ค.
์ฆ‰, ๋“ฑ๋ก๋˜์ง€์•Š๋Š” ๊ฒƒ์€ vm.$data.double๊ณผ vm.double๊ฐ„์˜ ๊ฒฐํ•ฉ์ด ์กด์žฌํ•˜์ง€๋„ ์•Š์•„์„œ๋ผ๊ณ  ์ƒ๊ฐ๋„ ๋“ ๋‹ค.
(์‹ค์ œ๋กœ vm.double=100์„ ํ•˜๊ณ  vm.$data.double์„ ๊ด€์ฐฐํ•˜๋ฉด ์กด์žฌํ•˜์ง€์•Š๋Š”๋‹ค. )


๋ถˆ๋ณ€์„ฑ

๐Ÿง„ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ์ฒด๊ฐ€ ์•„๋‹Œ ํ•จ์ˆ˜๋กœ ๋ฐ˜ํ™˜ํ•ด์•ผํ•˜๋Š” ์ด์œ 

๊ฐ„๋‹จํ•œ ์˜ˆ์‹œ

๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ์˜ˆ์‹œ๋ฅผ ๋“ค์–ด๋ณด์ž

const obj1 = {
  data : {
    count : 0
  }
}

const obj2 = {
  data() {
    return {
      count : 0
    }
  }
}

function P(data){
  this.change = ()=>{
    data.count += 10;
  }
  this.ret = () => {
    return data.count;
  }
}

let A = new P(obj1.data)
let B = new P(obj1.data)
let C = new P(obj2.data())
let D = new P(obj2.data())

A.change()
console.log(A.ret())	//10
console.log(B.ret())	//10
// A์— ์˜ํ–ฅ์„ ๋ฐ›์•„ B๊ฐ€ ๋ณ€๊ฒฝ

C.change()
console.log(C.ret())	//10
console.log(D.ret())	//0
// C์— ์˜ํ–ฅ์„ ๋ฐ›์ง€์•Š์•„ D๋Š” ๋ณ€๊ฒฝX
  • ๊ฒฐ๊ณผ๋Š” ์ด์™€ ๊ฐ™๋‹ค.

์ฆ‰, ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•œ ๋Œ€์ƒ์€ ํ•ด๋‹น ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๋ฉด ์ด์™€ ์—ฐ๊ด€๋œ ๊ฐ’ ๋˜ํ•œ ๋ณ€ํ•˜๊ฒŒ ๋˜๋Š” call by reference์— ์˜ํ–ฅ์„ ๋ฐ›๋Š”๋‹ค.

์ด๋ฅผ ์„œ๋กœ๊ฐ„์˜ ์—ฐ๊ด€์„ ์—†์• ๊ธฐ ์œ„ํ•ด์„œ ํ•ด๋‹น return ๊ฐ’์œผ๋กœ ๊ฐ์ฒด๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋„ฃ์œผ๋ฉด ๊ฐ’์ด ๋ณ€ํ•ด๋„ ๋‹ค๋ฅธ ๊ฐ’์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š”๋‹ค.


๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ฐ์ฒด๊ฐ€ ์•„๋‹Œ ๊ฐ’์œผ๋กœ ๋ฐ›๋Š”๋‹ค๋ฉด?

function P({count}){
  this.change = ()=>{
    count += 10;
  }
  this.ret = () => {
    return count;
  }
}

Pํ•จ์ˆ˜๊ฐ€ ์ด์™€๊ฐ™์ด ๋ณ€๊ฒฝ๋œ๋‹ค๋ฉด ๊ฐ’์„ ๋ฐ›์€๊ฒƒ์ด๋‹ˆ call by value๋กœ
์„œ๋กœ๊ฐ„์˜ ์˜ํ–ฅ์—†์ด ์•„๋ž˜์™€ ๊ฐ™์ด ์ถœ๋ ฅ๋  ๊ฒƒ์ด๋‹ค.

110
100
110
100


this.count๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด?

function P(data){
  this.count = data.count;
  this.change = ()=>{
    this.count += 10;
  }
  this.ret = () => {
    return this.count;
  }
}

Pํ•จ์ˆ˜๊ฐ€ ์ด์™€๊ฐ™์ด ๋ณ€๊ฒฝ๋œ๋‹ค๋ฉด data.count๋ผ๋Š” value๊ฐ’์„ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ์„œ๋กœ๊ฐ„์˜ ์˜ํ–ฅ์—†์ด ์œ„์™€ ๊ฐ™๋‹ค.


๐Ÿง„ new Proxy

๊ฐ์ฒด์™€ ๋ฆฌํ„ดํ•œ ํ•จ์ˆ˜ ์ฐจ์ด

const App1 = {
    data :  {
        count: 0
    }
  }
  const proxyA = new Proxy(App1.data,{
    get(target, key){
      return target[key]
    },
    set(target, key, value){
      target[key] = value * 2
    }
  })

  const proxyB = new Proxy(App1.data,{
    get(target, key){
      return target[key]
    },
    set(target, key, value){
      target[key] = value * 2
    }
  })


  const App2 = {
    data()  {
      return {count : 0}
    }
  }
  const proxyC = new Proxy(App2.data(),{
    get(target, key){
      return target[key]
    },
    set(target, key, value){
      target[key] = value * 2
    }
  })

  const proxyD = new Proxy(App2.data(),{
    get(target, key){
      return target[key]
    },
    set(target, key, value){
      target[key] = value * 2
    }
  })

๊ฐ์ฒด๋ฅผ ์ง์ ‘ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ฃผ์—ˆ๋˜ proxyA,proxyB๋Š” ์„œ๋กœ ์˜ํ–ฅ์„ ๋ฐ›์•„ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜์—ˆ๊ณ 
returnํ•œ ๊ฐ์ฒด๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ฃผ์—ˆ๋˜ proxyC,proxyD๋Š” ์„œ๋กœ ์˜ํ–ฅ์„ ๋ฐ›์ง€์•Š์•„ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜์ง€์•Š์•˜๋‹ค.


๐Ÿง„ Vue

  const App = {
    data() {
      return {
        counter: 0
      }
    }
  }

  const vm1 = Vue.createApp(App).mount('#app')
  const vm2 = Vue.createApp(App).mount('#btn')

proxy์™€ ์œ ์‚ฌํ•œ Vue์—์„œ๋Š” ํ•ด๋‹น App ์ปดํฌ๋„ŒํŠธ๋ฅผ ์žฌํ™œ์šฉํ•˜๊ธฐ์œ„ํ•ด ์žฌ์‚ฌ์šฉํ• ๋•Œ ์„œ๋กœ๊ฐ„์˜ ์˜ํ–ฅ์œผ๋กœ ์˜ค๋ฅ˜๊ฐ€ ๋‚˜๋Š” ๊ฒƒ์„ ๋ง‰๊ธฐ ์œ„ํ•ด์„œ
์ด์™€๊ฐ™์ด return์œผ๋กœ ๊ฐ์ฒด๋ฅผ ๋ฐ›์•„์ฃผ๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.


์ •๋ฆฌ

์šฐ๋ฆฌ๋Š” ์–ด๋– ํ•œ ๊ฐ’์„ ๋ฐ›์„ ๋•Œ ๊ทธ ๊ฐ’์ด ์›์‹œํ˜•์ธ์ง€ ์ฐธ์กฐํ˜•์ธ์ง€์— ๋”ฐ๋ผ
ํ•ด๋‹น ๊ฐ’(์›์‹œํ˜•/์ฐธ์กฐํ˜•)์„ ๋ณ€๊ฒฝํ•˜์˜€์„ ๋•Œ
์ด๊ฒƒ์„ ๋‹ค๋ฅธ ๊ณณ์—์„œ๋„ ์‚ฌ์šฉํ•œ ๊ณณ์—์„œ ์˜ํ–ฅ์„ ๋ฐ›๋Š”๋‹ค๋ฉด ์ฐธ์กฐํ˜•
๋‹ค๋ฅธ ๊ณณ์—์„œ ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๋Š”๋‹ค๋ฉด ์›์‹œํ˜•์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์ด๋•Œ ์ฐธ์กฐํ˜•์„ ์“ฐ๊ธดํ•˜๋˜ ์„œ๋กœ๊ฐ„์˜ ์˜ํ–ฅ์„ ์ฃผ๊ณ ์‹ถ์ง€ ์•Š๊ฒŒ ๋งŒ๋“ค๋ ค๋ฉด
์ง์ ‘ ์“ฐ๋Š”๊ฒƒ์ด ์•„๋‹Œ ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ๋ฆฌํ„ดํ•œ ์ƒํƒœ์˜ ์ฐธ์กฐํ˜•์„ ๋ฐ˜ํ™˜ํ•ด์„œ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค.
app.data (X) -> app.data()

์ฆ‰, vue์—์„œ๋Š” ์ฐธ์กฐํ˜•๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋˜ ์ปดํฌ๋„ŒํŠธ๊ฐ„ ์žฌ์‚ฌ์šฉ์— ์žˆ์–ด์„œ ํ•ด๋‹น ๊ฐ’๋“ค์˜ ๋…๋ฆฝ์„ฑ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด ๋ฆฌํ„ดํ•œ ์ƒํƒœ์˜ ์ฐธ์กฐํ˜•์„ ๋ฐ˜ํ™˜์„ ์ด์šฉํ•œ๋‹ค.

์ข‹์€ ์›นํŽ˜์ด์ง€ ์ฆ๊ฒจ์ฐพ๊ธฐ