JavaScript使用Proxy編寫一個取值限制器
前言
最近一直在開發(fā)低代碼平臺的東西,由于項目里面東西有點多,取值或調(diào)用起來比較麻煩,特別是那些實例的特殊函數(shù)和變量。
所以我實現(xiàn)了一個實例收集器,讓開發(fā)者的權(quán)限變得非常高,細節(jié)就不聊了。
盡管這樣子會讓開發(fā)的體驗變得很簡單,但是大家都知道最便宜的東西往往是最昂貴的,當你可以隨意在項目中讀取到不同組件的實例的時候,很容易導致某一個組件和另一個風馬牛不相及的組件產(chǎn)生關聯(lián),當某一側(cè)不當操作修了實例的某些內(nèi)容的話,很可能導致隱藏且嚴重的bug。
因此對于這種上帝的操作 必須進行限制,因此對此我創(chuàng)建了一個取值限制器來進行約束,代碼很簡單,不妨一看。
源碼實現(xiàn)
// 初始化 限制proxy生成函數(shù) 的 構(gòu)造函數(shù) // fn 校驗當前對象是否可以讀取 const LimitProxyConstructorFn = (fn) => { // 限制proxy // target 需要劫持的對象 const createLimitProxy = (target) => { return new Proxy(target, { get(target, property) { const res = Reflect.get(target, property); const isLegal = fn(property); // 判斷當前取值是否是對象,因為對象可能要限制取值 if (typeof res === "object" && res !== null) { // 合法對象 返回一個禁止賦值但支持取值的proxy對象 if (isLegal) { return new Proxy(target, { get(target, property) { return Reflect.get(target, property); }, set() { throw new Error("無法寫入屬性"); }, }); } // 如果不合法,則遞歸創(chuàng)建 限制proxy return createLimitProxy(res); } else { // 如果當前項不是對象,判斷是否合法,合法則返回,反之異常 if (isLegal) return res; throw new Error("取值不合法"); } }, set() { throw new Error("無法寫入屬性"); }, }); }; return createLimitProxy; };
測試用例
初始化限制proxy對象構(gòu)造函數(shù)
效果如下:
limitProxy 是一個proxy代理對象
看到藍色框里面的是取值操作,只有以__
開頭的屬性才能讀取。
如果__
開頭的屬性是一個對象則,該對象下所有的屬性都可以讀取。
反之認為讀取不合法。
可以看到紅框里面都是賦值操作,限制proxy禁用了所有的賦值操作,保證原數(shù)據(jù)的安全
代碼解釋
這段代碼的作用是創(chuàng)建一個可以限制對象屬性讀取和寫入操作的代理對象生成函數(shù)。傳入的驗證函數(shù) fn
用于確定哪些屬性是合法的。
生成的代理對象會根據(jù)驗證函數(shù)的結(jié)果,限制對屬性的讀取和寫入操作。
代碼解釋:
- 代碼定義了一個限制proxy函數(shù)的生成函數(shù)
LimitProxyConstructorFn
,該函數(shù)接受一個參數(shù)fn
,用于驗證當前對象是否可以讀取,fn
接受一個一個參數(shù)property
,即當前讀取的對象的key的名稱,需要返回boolean
判斷是否合法。 - 函數(shù)內(nèi)部定義了一個名為
createLimitProxy
的函數(shù),它接受一個參數(shù)target
,表示需要劫持的對象。createLimitProxy
函數(shù)使用new Proxy()
創(chuàng)建一個代理對象來限制目標對象的操作。
代理對象的 get
處理邏輯如下:
使用 Reflect.get()
獲取原始對象 target
的屬性值,并將結(jié)果存儲在變量 res
中。
調(diào)用驗證函數(shù) fn
并傳入屬性名稱 property
,將結(jié)果存儲在變量 isLegal
中,用于判斷屬性是否合法。
如果取值 res
是對象(不包括 null
),則進行進一步處理:
- 如果對象合法(
isLegal
為true
),則返回一個新的代理對象,該對象禁止賦值但允許取值。這個新代理對象的get
處理邏輯與原始代理對象相同,即返回原始對象的屬性值,而set
處理邏輯拋出一個錯誤,表示無法寫入屬性。 - 如果對象不合法,則遞歸調(diào)用
createLimitProxy
函數(shù),創(chuàng)建針對該對象的限制代理,并返回限制代理對象。
如果取值 res
不是對象,則判斷屬性是否合法:
- 如果屬性合法,則直接返回取值
res
。 - 如果屬性不合法,則拋出一個錯誤,表示取值不合法。
代理對象的 set
處理邏輯與上述相同,無論是對原始對象還是對代理對象進行屬性賦值操作,都會拋出一個錯誤,表示無法寫入屬性。
構(gòu)造函數(shù) LimitProxyConstructorFn
返回內(nèi)部定義的 createLimitProxy
函數(shù),以便可以使用該函數(shù)來生成限制代理對象。
總結(jié)
總的來說這個東西還挺有意思的,特別是那種需要限制取值權(quán)限的場景,代碼也很少,感興趣的朋友不妨了解一下,當然代碼還有不少優(yōu)化空間。
到此這篇關于JavaScript使用Proxy編寫一個取值限制器的文章就介紹到這了,更多相關JavaScript Proxy取值限制器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
解決function函數(shù)內(nèi)的循環(huán)變量
鼠標放到指定的行上自動彈出當前的個數(shù),從0開始,這個功能方便我們在tab切換中定位2008-10-10微信小程序如何根據(jù)不同用戶切換不同TabBar(簡單易懂!)
小程序中我們可能需要根據(jù)不同的權(quán)限展示不同的tabbar,下面這篇文章主要給大家介紹了關于微信小程序如何根據(jù)不同用戶切換不同TabBar的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-04-04Three.js中如何使用CSS3DRenderer和CSS3DSprite實現(xiàn)模型標簽文字
在Three.js中,使用CSS3DRenderer和CSS3DSprite可以輕松地實現(xiàn)模型標簽文字的效果,為場景中的模型提供更直觀的信息展示,本文將介紹如何使用這兩個工具來實現(xiàn)模型標簽文字,并提供相應的代碼示例,感興趣的朋友跟隨小編一起看看吧2024-05-05