Javascript Proxy对象 简介
Javascript Proxy對象 簡介
本文轉載自:眾成翻譯
譯者:eJayYoung
鏈接:http://www.zcfy.cc/article/4755
原文:https://blog.campvanilla.com/advanced-guide-javascript-proxy-objects-introduction-301c0fce9432
Javascript Proxy對象
改變你操作對象的方式
Proxies 是Javasript對象的中間件
…或者說至少是那種很早的版本。
ES6 中引入Proxies,讓你可以自定義Object的基本操作。例如,get就是Object的基礎操作方法。
const obj = {val: 10 }; console.log(obj.val);這里,console.log()表達式在對象obj上執行get方法來獲取val的值。
另一個對象的基本操作方法是 set。
const obj = {val: 10 }; obj.val2 = 20;這里,set方法用來給對象obj設置一個新的值。
如何創建Proxy?
const proxiedObject = new Proxy(initialObj, handler);調用Proxy構造函數,new Proxy()將返回一個對象,不僅包含了initialObj里的值,而且其基本操作(如get 和 set)現在可以通過handler對象來指定一些自定義邏輯。
我們寫個例子來理解這個概念,
const handler = {get: function() {console.log('A value has been accessed');} }const initialObj = {id: 1,name: 'Foo Bar' }const proxiedObj = new Proxy(initialObj, handler);console.log(proxiedObj.name);現在,如果我們沒有構造一個Proxy對象,執行第14行的console.log(proxiedObj.name)會在控制臺輸出 “Foo Bar”。
不過現在我們定義了一個Proxy,并在第三行get方法中定義了一些自定義邏輯。
現在執行console.log(proxiedObj.name)會在控制臺輸出 “A value has been accessed”。
仔細看,你會發現控制臺中實際上有兩條記錄。 “A value has been accessed” 和 undefined。 為什么?��
get運算符的默認實現是返回Object中存儲的值。由于我們將它重寫為只記錄一條語句,該值永遠不會返回,因此第14行的console.log()輸出undefined。
讓我們來解決這個問題!
get運算符有兩個參數 - 對象本身和被訪問的屬性。
const handler = {get: function(obj, prop) {console.log('A value has been accessed');return obj[prop]; // 返回訪問的key在obj的值} }const initialObj = {id: 1,name: 'Foo Bar' }const proxiedObj = new Proxy(initialObj, handler);console.log(proxiedObj.name); 返回屬性值好多了吧! ��
我們為get提供的自定義覆蓋被稱為“攔截器”(大概基于操作系統攔截的概念)。 handler對象基本上是一個包含一組“攔截”的對象,每當訪問對象屬性時都會被觸發。
我們給set也添加一個“攔截器”。 我們將做同樣的事情 - 任何時候設置一個值,我們將記錄被修改的屬性,以及為該鍵設置的值。
set操作符有三個參數 - 對象本身,被訪問的屬性和為該屬性設置的值。
const handler = {get: function(obj, prop) {console.log('A value has been accessed');return obj[prop];},set: function(obj, prop, value) {console.log(`${prop} is being set to ${value}`);} }const initialObj = {id: 1,name: 'Foo Bar' }const proxiedObj = new Proxy(initialObj, handler);proxiedObj.age = 24 添加set “攔截器”這里,在第18行進行的訪問將觸發第6行定義的功能,該功能將記錄正在訪問的屬性和正在設置的值。
Set “攔截器”?—— 控制臺的輸出一個真實的例子
假設我們有一個定義叫person的對象
const person = {id: 1,name: 'Foo Bar' };如果我們想讓這個對象的id屬性是一個私有屬性呢? 沒人能夠通過person.id訪問這個屬性,如果有人這樣做,我們需要拋出一個錯誤。 我們將如何做到這一點?
讓Proxies來拯救吧!����?��
我們所需要做的就是給這個對象創建一個Proxy,并覆蓋get運算符來阻止我們訪問id屬性!
const handler = {get: function(obj, prop) {if (prop === 'id') { // Check if the id is being accessedthrow new Error('Cannot access private properties!'); // Throw an error} else {return obj[prop]; // If it's not the id property, return it as usual}} }const person = {id: 1,name: 'Foo Bar' }const proxiedPerson = new Proxy(person, handler);console.log(proxiedPerson.id); 阻止訪問私有屬性這里,在我們給get創建的“攔截器”,我們檢查被訪問的屬性是否是id屬性,如果是的話,我們會拋出一個錯誤。 否則,我們照常返回值。
私有屬性?—?控制臺輸出另一個極好的用例是校驗。 通過設置set“攔截器”,我們可以在設置值之前添加自定義驗證。 如果該值不符合驗證,我們可以拋出一個錯誤!
const handler = {set: function(obj, prop, value) {if (typeof value !== 'string') {throw new Error('Only string values can be stored in this object!');} else {obj[prop] = value;}} }const obj = {};const proxiedObj = new Proxy(obj, handler);console.log(proxiedObj); // This will log an empty object proxiedObj.name = 'Foo Bar'; // This should be allowed console.log(proxiedObj); // This will log an object with the name property setproxiedObj.age = 24; // This will throw an error. 自定義對象的屬性校驗 自定義校驗 - 控制臺輸出在上面的例子中,我們已經看到了get和set“陷阱”。 實際上可以設置更多的“陷阱”。 你可以在這里找到整個列表。
Proxy對象只是在閱讀關于它們的這篇文章之后才進入我的視野,我已經可以在我每天寫的代碼中看到它們的用處了!
如果你之前在項目或工作中使用過Proxies,我很樂意聽到!��
~最后~
如果您覺得這篇文章對您有用,請點個贊��!
在什么地方卡住了,需要更多的幫助,還是只想打個招呼? 在Hashnode 給我直接發問題,或者在Twitter上Call我。 你也可以在Github上找到我。��
總結
以上是生活随笔為你收集整理的Javascript Proxy对象 简介的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WinDbg 命令三部曲:(一)WinD
- 下一篇: js常用的2中排序方法:冒泡排序和快速排