vue3中的Proxy一定要用Reflect的原因解析
用過(guò)vue的知道,vue的響應(yīng)實(shí)現(xiàn)用的Proxy,且里面是配合Reflect用的,查看Proxy和Reflect文檔最顯眼的是Reflect對(duì)象的靜態(tài)方法和Proxy代理方法的命名相同,Reflect可以操作對(duì)象使用, proxy可以代理對(duì)象,但沒(méi)有找到為啥有時(shí)一定要在Proxy代理方法中使用Reflect
基本操作
Reflect對(duì)象的靜態(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}疑問(wèn)
如果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簡(jiǎn)單多了
不一樣的對(duì)象, 帶有g(shù)et的對(duì)象
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)該代理中用的原對(duì)象取值所以this指向了原對(duì)象,所以值為false
雖然this指錯(cuò)了,但得到值還是正確定,這不是一定的理由
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這就有問(wèn)題了,輸出的結(jié)果都和期望的不一樣了,this應(yīng)該指向child,但指向了parent
Reflect上場(chǎng)
要是Reflect.get(obj, prop)換成obj[prop],這等于沒(méi)換,意義和結(jié)果是一樣的,這不是還有一個(gè)receiver參數(shù)沒(méi)有用嘛
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)然和期望一致,receiver的不是指代理對(duì)象,也不是指原對(duì)象,而是執(zhí)行上下文(有句話是這么說(shuō)的,不用特定方式改變this的情況下,誰(shuí)調(diào)用指向誰(shuí),這就是期望的),這里child調(diào)用的value所以期望的指向應(yīng)該是child, 這里你可能想到直接用receiver[prop]不行了,這樣會(huì)出現(xiàn)執(zhí)行溢出,receiver[prop]相當(dāng)于child.value,child.value還沒(méi)執(zhí)行完,receiver[prop]又執(zhí)行了,就會(huì)無(wú)限在執(zhí)行
Reflect.get(target, key, receiver)中的receiver參數(shù)修改了this指向,不加this指向target, 加了后指向receiver
代理對(duì)象中有用到
this時(shí)一定要用到Reflect,這樣才能得到一直符合期望的值
總結(jié)
vue3中的代理對(duì)象到得的都是符合期望的值,在攔截中做了收集和更新,所以一定要在Proxy的攔截函數(shù)中使用Reflect處理
怎么一直拿到符合期望的值,代理了像沒(méi)有代理一樣
get: function (...arg) {
return Reflect.get(...arg);
},到此這篇關(guān)于為啥vue3中的Proxy一定要用Reflect的文章就介紹到這了,更多相關(guān)vue3中Proxy使用Reflect內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue項(xiàng)目打包清除console.log的四種方法總結(jié)
大家在項(xiàng)目開(kāi)發(fā)的時(shí)候,需要看看一些后端接口返回的結(jié)果,會(huì)多次使用console.log項(xiàng)目開(kāi)發(fā)完成打包的時(shí)候,發(fā)現(xiàn)控制臺(tái)一堆的console.log,非常頭疼,下面這篇文章主要給大家介紹了關(guān)于vue項(xiàng)目打包清除console.log的四種方法,需要的朋友可以參考下2023-04-04
vue3成功創(chuàng)建項(xiàng)目后?run?serve啟動(dòng)項(xiàng)目報(bào)錯(cuò)的解決
這篇文章主要介紹了vue3成功創(chuàng)建項(xiàng)目后?run?serve啟動(dòng)項(xiàng)目報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03
vue限制輸入框只能輸入8位整數(shù)和2位小數(shù)的代碼
這篇文章主要介紹了vue限制輸入框只能輸入8位整數(shù)和2位小數(shù),文中我們使用v-model加watch 實(shí)現(xiàn)這一個(gè)功能,代碼簡(jiǎn)單易懂,需要的朋友可以參考下2019-11-11
vue實(shí)現(xiàn)購(gòu)物車(chē)的監(jiān)聽(tīng)
這篇文章主要為大家詳細(xì)介紹了利用vue的監(jiān)聽(tīng)事件實(shí)現(xiàn)一個(gè)簡(jiǎn)單購(gòu)物車(chē),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04
vue3在構(gòu)建時(shí)使用魔法糖語(yǔ)法時(shí)defineProps和defineEmits的注意事項(xiàng)小結(jié)
在 Vue 3.2+ 版本中,可以使用 <script setup> 替代傳統(tǒng)的 script標(biāo)簽來(lái)編寫(xiě)組件,它提供了更簡(jiǎn)潔的語(yǔ)法來(lái)編寫(xiě) Composition API 代碼,這篇文章主要介紹了vue3在構(gòu)建時(shí)使用魔法糖語(yǔ)法時(shí)defineProps和defineEmits的注意事項(xiàng)小結(jié),需要的朋友可以參考下2024-04-04
vue2路由方式--嵌套路由實(shí)現(xiàn)方法分析
這篇文章主要介紹了vue2嵌套路由實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了vue2嵌套路由基本實(shí)現(xiàn)方法與操作注意事項(xiàng),需要的朋友可以參考下2020-03-03

