JAvascriptのオブザーバーモード

2235 ワード

オブザーバモード
適用シーン:
シーン1:観察したデータオブジェクトが変化すると、対応する関数が自動的に呼び出されます.例えばvueの双方向バインド;シーン2:オブジェクト内のメソッドを呼び出すたびに、対応する「アクセス」ロジックが呼び出されます.例えば、テストフレームワークにエネルギーを与えるspy関数.
シーン1:双方向バインド
Object.definePropertyはObjectを使用します.defineProperty(obj,props,descriptor)は、vue双方向バインドのコアでもあるオブザーバモードを実装します.例は、objのvalueを変更すると、対応する相関関数が自動的に呼び出されます.
 var obj ={
    data: {list:[]}
  }
  Object.defineProperty(obj,'list',{
    get(){
      return this.data['list']
    },
    set(val){
      console.log('     ')
      this.data['list'] = val
    }
  })

ProxyProxy/ReflectはES 6が導入した新しい特性であり、観察者モードを完了するためにも使用できます.例は以下の通りです(効果は同じです).
   var obj = {
     value: 0
   }
   var proxy = new Proxy(obj,{
     set: function(target,key,value,receiver){
       console.log('      ')
       Reflect.set(target,key,value,receiver)
     }
   })
   proxy.value = 1

シーン2ではsinonフレームワークのspy関数を実現します.
 const sinon = {
     analyze: {},
     spy:function(obj,fnName){
      const that = this
      const oldFn = Object.getOwnPropertyDescriptor(obj,fnName).value
      Object.defineProperty(obj,fnName,{
        value:function(){
          oldFn()
          if(that.analyze[fnName]){
            that.analyze[fnName].count = ++that.analyze[fnName].count
          }else{
            that.analyze[fnName] = {}
            that.analyze[fnName].count = 1
          }
          console.log(`${fnName}    ${that.analyze[fnName].count}`)
        }
      })
     }
   }
   const obj = {
     someFn: function(){
      console.log(`my name is someFn`)
     }
   }
   sinon.spy(obj,'someFn')
   obj.someFn()
  //  my name is someFn
  // someFn      
  obj.someFn()
  // my name is someFn
  // someFn     2 
             ,       '  '  。         spy   ;

vueが3.0バージョンでProxy再構築を使用した理由
まずObjectを羅列します.defineProperty()の欠点:
  • Object.defineProperty()は、push/popなどの配列参照の不変の動作を監視しません.
  • Object.defineProperty()は、オブジェクトのプロパティの変更のみを監視できます.すなわち、深さネストされたオブジェクトがある場合は、
  • を再バインドする必要があります.
  • Object.defineProperty();

  • Proxyのメリットについて
  • は配列の変更をハイジャックすることができる.
  • definePropertyは属性に対するハイジャックであり、Proxyは対象に対するハイジャックである.