JAvascriptのオブザーバーモード
2235 ワード
オブザーバモード
適用シーン:
シーン1:観察したデータオブジェクトが変化すると、対応する関数が自動的に呼び出されます.例えばvueの双方向バインド;シーン2:オブジェクト内のメソッドを呼び出すたびに、対応する「アクセス」ロジックが呼び出されます.例えば、テストフレームワークにエネルギーを与えるspy関数.
シーン1:双方向バインド
Object.definePropertyはObjectを使用します.defineProperty(obj,props,descriptor)は、vue双方向バインドのコアでもあるオブザーバモードを実装します.例は、objのvalueを変更すると、対応する相関関数が自動的に呼び出されます.
ProxyProxy/ReflectはES 6が導入した新しい特性であり、観察者モードを完了するためにも使用できます.例は以下の通りです(効果は同じです).
シーン2ではsinonフレームワークのspy関数を実現します.
vueが3.0バージョンでProxy再構築を使用した理由
まずObjectを羅列します.defineProperty()の欠点: Object.defineProperty()は、push/popなどの配列参照の不変の動作を監視しません. Object.defineProperty()は、オブジェクトのプロパティの変更のみを監視できます.すなわち、深さネストされたオブジェクトがある場合は、 を再バインドする必要があります. Object.defineProperty();
Proxyのメリットについては配列の変更をハイジャックすることができる. definePropertyは属性に対するハイジャックであり、Proxyは対象に対するハイジャックである.
適用シーン:
シーン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()の欠点:
Proxyのメリットについて