在 Javascript 中,代理程式可讓您擷取特定物件操作並自訂它們。代理人充當物件和「現實世界」之間的中介。因此,您可以增強物件的基本操作以實現更複雜的邏輯或重新定義基本操作以滿足您的需求。
用例包括:
Proxy 有兩個參數:
const target = { greeting1: "Hello", greeting2: "Good morning" } const handler = { get(target, prop, receiver) { return target[prop] + " friends!" } } const proxy = new Proxy(target, handler) console.log(proxy.greeting1) // Hello friends! console.log(proxy.greeting2) // Good morning friends!
在這個例子中,我們定義了一個代理。目標物件有兩個屬性。我們定義一個提供 get() 處理程序實作的處理程序。 get 陷阱攔截對目標物件上任何屬性的訪問,在其中,我們可以根據需要修改行為。
透過這種設置,這意味著每次我們要存取目標物件中的屬性時,處理程序都會攔截它,並運行我們實現的程式碼。在我們的例子中,它只取得屬性值並新增好友! .
代理通常與 Reflect API 一起使用。 Reflect 提供與代理陷阱同名的方法。如其名稱所示,它反映了呼叫對應物件內部方法的語義。
const target = { greeting1: "Hello", greeting2: "Good morning" } const handler = { get(target, prop, receiver) { return Reflect.get(...arguments) + " friends!" } } const proxy = new Proxy(target, handler) console.log(proxy.greeting1) // Hello friends! console.log(proxy.greeting2) // Good morning friends!
Reflect 不需要使用代理,但使用 Reflect 可以讓我們確保行為與本機 Javascript 引擎操作相符。它還確保與未來更新的兼容性,防止意外的副作用並簡化程式碼。如果沒有它,開發人員將不得不重新實作屬性存取、賦值、刪除等行為……這可能容易出錯並且與 Javascript 的本機行為不一致。
讓我們建立一些範例來探索我們可以使用 Proxy 做什麼。
在我們的第一個範例中,假設我們希望記錄對物件執行的操作。每當我們取得、設定或刪除屬性時,我都想列印到控制台。這對於調試目的可能很有用。
const target = { name: "Damien", age: 32, status: "WRITING" } const loggerHandler = { get(target, prop, receiver) { if (prop in target) { console.log(`[LOG] Accessing property ${prop}. Current value is ${target[prop]}`) return Reflect.get(...arguments) } else { console.error(`[LOG] Error accessing non-existent property ${prop}`) } }, set(target, key, value) { console.log(`[LOG] Setting property ${key}. New value: ${value}`) return Reflect.set(...arguments) }, deleteProperty(target, prop) { console.warn(`[LOG] Deleting property: ${prop}`) return Reflect.deleteProperty(...arguments) } } const proxy = new Proxy(target, loggerHandler) proxy.name // [LOG] Accessing property name. Current value is Damien proxy.status // [LOG] Accessing property status. Current value is WRITING proxy.name = "Bob" // [LOG] Setting property name. New value: Bob proxy.status = "NAPPING" // [LOG] Setting property status. New value: NAPPING proxy.job = "Developer" // [LOG] Setting property job. New value: Developer delete proxy.job // [LOG] Deleting property: job proxy.job // [LOG] Error accessing non-existent property job
我們定義了一個loggerHandler,它重新定義了3個基本操作:取得、設定和刪除。對於每個操作,我們都會將一些內容記錄到控制台,描述正在發生的情況。 Proxy 的美妙之處在於,我們不需要每次都寫控制台語句。我們像往常一樣與物件交互,代理負責記錄日誌行為。很酷不是嗎?
在我們的第二個範例中,我們將使用代理來執行表單資料的輸入驗證。
const validationRules = { name: value => value.length >= 3 || "Name must be at least 3 characters long", age: value => Number.isInteger(value) || "Age must be a number", email: value => value.includes('@') || "Enter a valid email" } let formData = { name: "", age: null, email: "" } const formHandler = { set(target, key, value) { if (typeof value === "string") { value = value.trim() } const validationResult = validationRules[key](value) if (validationResult !== true) { console.error(`Validation failed for property ${key}: ${validationResult}`) return false; } return Reflect.set(...arguments) } } const formProxy = new Proxy(formData, formHandler) formProxy.age = "32 years old" // Validation failed for property age: Age must be a number formProxy.name = "Da" // Validation failed for property name: Name must be at least 3 characters long formProxy.email = "damcoss mail.com" // Validation failed for property email: Enter a valid email formProxy.age = 32 // OK formProxy.name = "Damien" // OK formProxy.email = "damcoss@mail.com" // OK
我們在這裡定義一個具有不同方法的對象,用於驗證值是否有效。然後,我們使用相同的邏輯。我們有要代理的目標物件 formData。在 formHandler 中,我們重新定義 set() 方法以將驗證規則套用至輸入值。
代理與 Reflect API 結合,是攔截和自訂物件操作的靈活且強大的工具。使用它們,您可以動態增強和控制行為。透過使用 Reflect API,您還可以確保行為與 Javascript 引擎一致。
代理通常在庫和框架中使用,以實現反應式程式設計、API 包裝器和屬性觀察等高階行為。
玩得開心❤️
以上是了解 Javascript 代理和 Reflect API的詳細內容。更多資訊請關注PHP中文網其他相關文章!