您好,登錄后才能下訂單哦!
這篇文章主要介紹“vue3中的Proxy為什么一定要用Reflect”的相關(guān)知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“vue3中的Proxy為什么一定要用Reflect”文章能幫助大家解決問題。
用過vue的知道,vue的響應(yīng)實現(xiàn)用的Proxy,且里面是配合Reflect用的,查看Proxy和Reflect文檔最顯眼的是Reflect對象的靜態(tài)方法和Proxy代理方法的命名相同,Reflect可以操作對象使用, proxy可以代理對象,但沒有找到為啥有時一定要在Proxy代理方法中使用Reflect
Reflect對象的靜態(tài)方法和Proxy代理方法的命名相同,都有13種,示例get,set如下
const tempObj = { a: 1 }; Reflect.get(tempObj, 'a'); // 返回 1 Reflect.set(tempObj, 'a', 2); // 返回true 表示設(shè)置成功, a的值變2 const tempObj1 = { a: 1 }; const handler = { get: function (obj, prop, receiver) { return prop === 'a' ? 1000 : obj[prop]; }, set: function (obj, prop, value, receiver) { console.log(prop); obj[prop] = prop === 'a' ? 6 : value; return true; }, }; const proxyObj = new Proxy(tempObj1, handler); proxyObj.a; // proxyObj => {a: 1000} proxyObj.a = 2; // proxyObj => {a: 6}
如果Proxy不做其它操作直接正常返回
const tempObj1 = { a: 1 }; const handler = { get: function (obj, prop, receiver) { return obj[prop]; }, set: function (obj, prop, value, receiver) { obj[prop] = value return true; }, }; const proxyObj = new Proxy(tempObj1, handler); proxyObj.a; // proxyObj => {a: 1} proxyObj.a = 2; // proxyObj => {a: 2}
以上面情況完P(guān)roxy可以不使用Reflect處理攔截,比使用Reflect簡單多了
不一樣的對象, 帶有g(shù)et的對象
const tempObj1 = { a: 1, get value() { console.log(this === proxyObj); // false return this.a; }, }; const handler = { get: function (obj, prop, receiver) { return obj[prop]; }, set: function (obj, prop, value, receiver) { obj[prop] = value; return true; }, }; const proxyObj = new Proxy(tempObj1, handler); proxyObj.value; // 1
上面value中的打印的值為false,期望的結(jié)果應(yīng)該true, 但應(yīng)該代理中用的原對象取值所以this指向了原對象,所以值為false
雖然this指錯了,但得到值還是正確定,這不是一定的理由
const parent = { a: 1, get value() { console.log(this === child); // false return this.a; }, }; const handler = { get: function (obj, prop, receiver) { return obj[prop]; }, set: function (obj, prop, value, receiver) { obj[prop] = value; return true; }, }; const proxyObj = new Proxy(parent, handler); const child = Object.setPrototypeOf({ a: 2 }, proxyObj); child.value; // 1
這就有問題了,輸出的結(jié)果都和期望的不一樣了,this應(yīng)該指向child,但指向了parent
Reflect上場
要是Reflect.get(obj, prop)
換成obj[prop]
,這等于沒換,意義和結(jié)果是一樣的,這不是還有一個receiver參數(shù)沒有用嘛
const parent = { a: 1, get value() { console.log(this === child); // true return this.a; }, }; const handler = { get: function (obj, prop, receiver) { Reflect.get(obj, prop) - return obj[prop]; + retrun Reflect.get(obj, prop, receiver) }, set: function (obj, prop, value, receiver) { - obj[prop] = value; + Reflect.get(obj, prop, value, receiver) return true; }, }; const proxyObj = new Proxy(parent, handler); const child = Object.setPrototypeOf({ a: 2 }, proxyObj); child.value; // 2
this
指向正確,結(jié)果也當(dāng)然和期望一致,receive
r的不是指代理對象,也不是指原對象,而是執(zhí)行上下文(有句話是這么說的,不用特定方式改變this的情況下,誰調(diào)用指向誰,這就是期望的),這里child
調(diào)用的value
所以期望的指向應(yīng)該是child
, 這里你可能想到直接用receiver[prop]
不行了,這樣會出現(xiàn)執(zhí)行溢出,receiver[prop]
相當(dāng)于child.value
,child.value
還沒執(zhí)行完,receiver[prop]
又執(zhí)行了,就會無限在執(zhí)行
Reflect.get(target, key, receiver)
中的receiver
參數(shù)修改了this
指向,不加this
指向target
, 加了后指向receiver
代理對象中有用到
this
時一定要用到Reflect
,這樣才能得到一直符合期望的值
vue3中的代理對象到得的都是符合期望的值,在攔截中做了收集和更新,所以一定要在Proxy
的攔截函數(shù)中使用Reflect
處理
get: function (...arg) { return Reflect.get(...arg); },
關(guān)于“vue3中的Proxy為什么一定要用Reflect”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識,可以關(guān)注億速云行業(yè)資訊頻道,小編每天都會為大家更新不同的知識點。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。