vue3中的Proxy為什麼一定要用Reflect
用過vue的知道,vue的響應實現用的Proxy,且裡面是配合Reflect用的,查看Proxy和Reflect文檔最顯眼的是Reflect物件的靜態方法和Proxy代理方法的命名相同,Reflect可以操作物件使用, proxy可以代理對象,但沒有找到為啥有時一定要在Proxy代理方法中使用Reflect
基本操作
Reflect對象的靜態方法和Proxy代理方法的命名相同,都有13種,範例get,set如下
const tempObj = { a: 1 }; Reflect.get(tempObj, 'a'); // 返回 1 Reflect.set(tempObj, 'a', 2); // 返回true 表示设置成功, 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}
以上面情況完Proxy可以不使用Reflect處理攔截,比使用Reflect簡單多了
不一樣的對象, 帶有get的對象
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,期望的結果應該true, 但應該代理中用的原對象取值所以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
這就有問題了,輸出的結果都和期望的不一樣了,this應該指向child,但指向了parent
Reflect上場
要是Reflect.get(obj, prop)
換成obj[prop]
,這等於沒換,意義和結果是一樣的,這不是還有一個receiver參數沒有用嘛
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
指向正確,結果也當然和期望一致,receive
r的不是指代理對象,也不是指原對象,而是執行上下文(有句話是這麼說的,不用特定方式改變this的情況下,誰調用指向誰,這就是期望的),這裡child
調用的value
所以期望的指向應該是child
, 這裡你可能想到直接用receiver[prop]
不行了,這樣會出現執行溢出,receiver[prop]
相當於child.value
,child.value
還沒執行完,receiver[prop]
又執行了,就會無限在執行
Reflect.get(target, key, receiver)
中的receiver
參數修改了this
指向,不加this
指向target
, 加了後指向receiver
#代理物件中有用到
this
時一定要用到Reflect
,這樣才能得到一直符合期望的值
#總結
vue3中的代理物件到得的都是符合期望的值,在攔截中做了收集和更新,所以一定要在Proxy
的攔截函數中使用Reflect
處理
怎麼一直拿到符合期望的值,代理了像沒有代理一樣
get: function (...arg) { return Reflect.get(...arg); },
以上是vue3中的Proxy為什麼一定要用Reflect的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

NginxProxyManager設定解析與最佳化概述:NginxProxyManager是一個基於Nginx的反向代理管理工具,可以幫助我們方便地設定和管理反向代理伺服器。在使用NginxProxyManager的過程中,我們可以透過對其組態進行解析與最佳化,提升伺服器的效能與安全性。設定解析:設定檔位置與結構:NginxProxyManag

想要實現頁面的局部刷新,我們只需要實現局部元件(dom)的重新渲染。在Vue中,想要實現這效果最簡單的方式方法就是使用v-if指令。在Vue2中我們除了使用v-if指令讓局部dom的重新渲染,也可以新建一個空白元件,需要刷新局部頁面時跳轉至這個空白元件頁面,然後在空白元件內的beforeRouteEnter守衛中又跳轉回原來的頁面。如下圖所示,如何在Vue3.X中實現點擊刷新按鈕實現紅框範圍內的dom重新加載,並展示對應的加載狀態。由於Vue3.X中scriptsetup語法中組件內守衛只有o

vue3+vite:src使用require動態導入圖片報錯和解決方法vue3+vite動態的導入多張圖片vue3如果使用的是typescript開發,就會出現require引入圖片報錯,requireisnotdefined不能像使用vue2這樣imgUrl:require(' …/assets/test.png')導入,是因為typescript不支援require所以用import導入,下面介紹如何解決:使用awaitimport

Vue實作部落格前端,需要實作markdown的解析,如果有程式碼則需要實作程式碼的高亮。 Vue的markdown解析函式庫很多,如markdown-it、vue-markdown-loader、marked、vue-markdown等。這些庫都大同小異。這裡選用的是marked,程式碼高亮的函式庫選用的是highlight.js。具體實現步驟如下:一、安裝依賴庫在vue專案下開啟命令窗口,並輸入以下命令npminstallmarked-save//marked用於將markdown轉換成htmlnpmins

學習Go語言文檔中的reflect.MakeFunc函數實作動態函數產生在Go語言中,reflect套件提供了一系列的函數和類型,用於在執行時間進行類型資訊的解析和操作。其中,reflect.MakeFunc函數是一個非常強大的函數,可以用來在運行時動態產生函數。 reflect.MakeFunc函數的定義如下:funcMakeFunc(typType,fn

最終效果安裝VueCropper組件yarnaddvue-cropper@next上面的安裝值針對Vue3的,如果時Vue2或想使用其他的方式引用,請訪問它的npm官方地址:官方教程。在元件中引用使用時也很簡單,只需要引入對應的元件和它的樣式文件,我這裡沒有在全域引用,只在我的元件檔案中引入import{userInfoByRequest}from'../js/api' import{VueCropper}from'vue-cropper&

NginxProxyManager下的容器與微服務的部署策略,需要具體程式碼範例摘要:隨著微服務架構的流行,容器化技術成為了現代軟體開發的重要組成部分。而在微服務架構中,NginxProxyManager扮演著很重要的角色,用來管理和代理微服務的流量。本文將介紹如何使用NginxProxyManager來部署和管理容器化的微服務,並提供相關的程式碼示

前言無論是vue還是react,當我們遇到多處重複程式碼的時候,我們都會想著如何重複使用這些程式碼,而不是一個檔案裡充斥著一堆冗餘程式碼。實際上,vue和react都可以透過抽組件的方式來達到復用,但如果遇到一些很小的程式碼片段,你又不想抽到另外一個檔案的情況下,相比而言,react可以在相同文件裡面宣告對應的小元件,或透過renderfunction來實現,如:constDemo:FC=({msg})=>{returndemomsgis{msg}}constApp:FC=()=>{return(
