<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
JavaScript 在 ES6 中,引入了一個新的物件型別 Proxy
,它可以用來代理另一個物件,並可以在代理過程中攔截、覆蓋和客製化物件的操作。Proxy
物件封裝另一個物件並充當中間人,其提供了一個捕捉器函數,可以在代理物件上攔截所有的操作,包括存取屬性、賦值屬性、函數呼叫等等。通過攔截這些操作,可以對代理物件進行客製化和控制。
在開始介紹 Proxy
物件前先了解 3 個術語:
target 目標物件
:要代理的物件或函數。handler 處理程式
:對代理的物件或函數執行某些操作的函數。traps 捕捉器
:這些是一些用於處理目標的函數。單擊此處閱讀有關陷阱的更多資訊。Proxy
物件的基本語法如下:
new Proxy(target, handler);
其中,target
是被代理的目標物件,handler
是一個物件,它包含了一些捕捉器函數,用來攔截代理物件的操作。
下面是一些常見的攔截操作和對應的捕捉器函數:
getPrototypeOf()
:Object.getPrototypeOf
方法的捕捉器。setPrototypeOf()
:Object.setPrototypeOf
方法的捕捉器。isExtensible()
:Object.isExtensible
方法的捕捉器。preventExtensions()
:Object.preventExtensions
方法的捕捉器。getOwnPropertyDescriptor()
:Object.getOwnPropertyDescriptor
方法的捕捉器。handler.defineProperty()
:Object.defineProperty
方法的捕捉器。get(target, propKey, receiver)
:攔截物件的讀取屬性操作,返回屬性值。set(target, propKey, value, receiver)
:攔截物件的設定屬性操作,返回一個布林值表示是否設定成功。has(target, propKey)
:攔截物件的 in
操作符,返回一個布林值表示物件是否包含該屬性。deleteProperty(target, propKey)
:攔截物件的 delete
操作符,返回一個布林值表示是否刪除成功。ownKeys()
:Object.getOwnPropertyNames
方法和 Object.getOwnPropertySymbols
方法的捕捉器如果目標物件是一個函數,可以使用下面 2 個捕捉器。
apply(target, thisArg, args)
:攔截函數的呼叫操作,返回撥用結果。construct(target, args, newTarget)
:攔截 new
操作符,返回一個物件。Proxy
在目標物件周圍建立一個不可檢測的屏障,將所有操作重定向到處理程式物件。如果傳送一個空的 handler
,代理只是原始物件的一個空包裝器。
const author = { name: "Quintion", age: 36, }; const proxyAuthor = new Proxy(author, {}); console.log(author.name); // Quintion console.log(proxyAuthor.name); // Quintion
為了賦予代理意義,需要向處理程式新增一些操作方法。
每當與一個物件互動時,都在呼叫一個內部方法。代理允許使用捕捉器攔截給定內部方法的執行。
因此,當執行 author.name
時,告訴 JavaScript 引擎呼叫內部 [[GET]]
方法來檢索 name
屬性。當執行 proxyAuthor.name
時,get
捕捉器會呼叫處理程式中定義的 get()
函數來執行,然後再將呼叫傳送到原始物件。
get()
方法有兩個必需的引數:
target
— 傳遞給代理的物件。property
— 存取的屬性的名稱。要自定義代理,在處理程式物件上定義函數。下面定義了 get
方法來記錄存取:
const handler = { get(target, property) { console.log(`捕捉器 GET:${property}`); return target[property]; }, };
為了讓呼叫通過,捕捉器 get
返回 target[property]
。使用方式如下:
const author = { name: "Quintion", age: 36, }; const handler = { get(target, property) { console.log(`捕捉器 GET[${property}]`); return target[property]; }, }; const proxyAuthor = new Proxy(author, handler); console.log(proxyAuthor.name);
執行後,將列印以下內容:
捕捉器 GET[name]
Quintion
set
捕捉器用於給目標物件進行賦值操作,返回值是一個布林值。set
捕捉器需要的引數如下:
target
— 傳遞給代理的物件。property
— 將被設定的屬性名或 Symbol。value
— 新的屬性值receiver
— 最初被呼叫的物件。下面通過 set
捕捉器驗證年齡值的輸入:
const handler = { set(target, property, value) { if (property === "age" && typeof value !== "number") { throw new TypeError("年齡必須是一個數位"); } target[property] = value; return true; }, };
下面嘗試將錯誤的型別值賦值給 age
,則會丟擲錯誤:
const proxyAuthor = new Proxy(author, handler); proxyAuthor.age = "young"; // 執行後丟擲異常:throw new TypeError("年齡必須是一個數位");
set()
方法應該返回一個布林值 true
用來表示賦值成功。 在嚴格模式下執行,並且返回一個假值或什麼都不返回,則會丟擲錯誤。
除了攔截對屬性的讀取和修改,Proxy
總共可以攔截 13 種操作。
通過 Proxy
物件的特徵,可以將其使用在下面這些場合:
代理Proxy
用於攔截和驗證對物件屬性的存取。如,可以建立一個代理來檢查使用者輸入的資料是否符合預期的格式,並拒絕不正確的資料。就如下面 age
屬性賦值判斷
代理Proxy
用於快取物件的操作結果,以避免重複計算。如,可以建立一個代理來攔截物件的某些方法,並將結果儲存在快取中,以便將來使用。
下面是一個基於 Proxy 的快取庫的範例:
class Cache { constructor() { this.cache = new Map(); this.proxy = new Proxy(this, { get(target, property) { if (property === "get") { return (key) => { return target.cache.get(key); }; } if (property === "set") { return (key, value) => { target.cache.set(key, value); }; } if (property === "has") { return (key) => { return target.cache.has(key); }; } if (property === "delete") { return (key) => { return target.cache.delete(key); }; } }, }); } }
在上面的程式碼中,定義了一個 Cache
類,該類中包含一個內部的 Map
物件用於儲存快取資料,並且定義了一個 proxy
物件作為該類的代理。
在 proxy
物件的 get
方法中,根據傳入的屬性名返回相應的方法。如果屬性名為 get
,則返回一個可以獲取快取值的方法;如果屬性名為 set
,則返回一個可以設定快取值的方法;如果屬性名為 has
,則返回一個可以判斷是否存在快取值的方法;如果屬性名為 delete
,則返回一個可以刪除快取值的方法。
下面是一個使用該快取庫的範例:
const cacheHelper = new Cache(); cacheHelper.set("foo", "bar"); console.log(cacheHelper.get("foo")); // "bar" console.log(cacheHelper.has("foo")); // true cacheHelper.delete("foo"); console.log(cacheHelper.get("foo")); // undefined console.log(cacheHelper.has("foo")); // false
在上面的程式碼中,建立了一個 Cache
物件,並呼叫其 set
方法設定快取值,然後呼叫其 get
方法獲取快取值,並呼叫其 has 方法判斷快取值是否存在,最後呼叫其 delete
方法刪除快取值。
代理Proxy
用於監視物件屬性的變化,並在屬性發生變化時觸發其他操作。如,建立一個代理來監視物件屬性的變化,並在屬性發生變化時更新頁面上的元素。
代理Proxy
用於防止誤操作,如,建立一個代理來攔截物件的某些方法,並在方法呼叫時檢查一些條件,以確保方法只在正確的上下文中呼叫。
代理Proxy
可以用於建立虛擬化物件。如,建立一個代理物件,用於代替某個物件的真實實現,並且在實際物件執行之前,對其進行修改或攔截。
上面介紹瞭如何使用代理Proxy
物件來監視物件,通過使用處理程式物件中的捕捉器方法向它們新增自定義行為,提供更高階的物件操作和控制功能,從而增強程式碼的可讀性和可維護性。
以上就是JavaScript 物件管家 Proxy的詳細內容,更多關於JavaScript物件Proxy的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45