」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 了解 Javascript 代理和 Reflect API

了解 Javascript 代理和 Reflect API

發佈於2024-11-08
瀏覽:365

Understanding Javascript

介绍

在 Javascript 中,代理使您能够捕获特定对象操作并自定义它们。代理充当对象和“现实世界”之间的中介。因此,您可以增强对象的基本操作以实现更复杂的逻辑或重新定义基本操作以满足您的需求。

用例包括:

  • 记录属性访问,对于调试很有用
  • 验证与对象的任何交互(例如表单验证)
  • 帮助强制
  • 的格式一致

Proxy 有两个参数:

  • target:就是你要代理的原始对象
  • handler:定义您将拦截的操作以及如何重新定义所述操作的对象

基本示例


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!



在这个例子中,我们定义了一个Proxy。目标对象有两个属性。我们定义一个提供 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 = "[email protected]" // OK


我们在这里定义一个具有不同方法的对象,用于验证值是否有效。然后,我们使用相同的逻辑。我们有要代理的目标对象 formData。在 formHandler 中,我们重新定义 set() 方法以将验证规则应用于输入值。

结论

代理与 Reflect API 相结合,是拦截和自定义对象操作的灵活而强大的工具。使用它们,您可以动态增强和控制行为。通过使用 Reflect API,您还可以确保行为与 Javascript 引擎一致。

代理通常在库和框架中使用,以实现高级行为,例如反应式编程、API 包装器和属性观察。

玩得开心❤️

版本聲明 本文轉載於:https://dev.to/damcosset/understanding-javascripts-proxies-and-reflect-api-1e6i?1如有侵犯,請洽[email protected]刪除
最新教學 更多>
  • MySQL中如何從VARCHAR日期中提取月份和年份?
    MySQL中如何從VARCHAR日期中提取月份和年份?
    如何將VARCHAR轉換為MySQL中的日期,並僅提取一個月和年 許多開發人員遇到需要將varChar值轉換為MySQL日期格式的VARCHAR值的需要,並提取月份和年度類似的特定日期組件。本文通過引導您瀏覽所涉及的步驟來解決這一共同挑戰。 str_to_date函數是通常用於將字符串轉換為日期...
    程式設計 發佈於2025-04-15
  • Python高效去除文本中HTML標籤方法
    Python高效去除文本中HTML標籤方法
    在Python中剝離HTML標籤,以獲取原始的文本表示Achieving Text-Only Extraction with Python's MLStripperTo streamline the stripping process, the Python standard librar...
    程式設計 發佈於2025-04-15
  • MySQL所有行如何高效存入數組進行數據操作?
    MySQL所有行如何高效存入數組進行數據操作?
    從array 實現此目的,您可以利用MySQL_Fetch_Array()函數,該功能將單個行檢索為關聯陣列。但是,此方法默認情況下僅獲取第一行。要訪問所有行,您可以使用一個while循環: = $ row; } echo json_encode($ array); ? > 此循環將遍歷結果...
    程式設計 發佈於2025-04-15
  • \“(1)vs.(;;):編譯器優化是否消除了性能差異?\”
    \“(1)vs.(;;):編譯器優化是否消除了性能差異?\”
    答案: 在大多數現代編譯器中,while(1)和(1)和(;;)之間沒有性能差異。編譯器: perl: 1 輸入 - > 2 2 NextState(Main 2 -E:1)V-> 3 9 Leaveloop VK/2-> A 3 toterloop(next-> 8 last-> 9 ...
    程式設計 發佈於2025-04-15
  • Axios新手必備:實用的Promise-based HTTP客戶端
    Axios新手必備:實用的Promise-based HTTP客戶端
    Axios 关键要点 Axios 是一个流行的基于 Promise 的 HTTP 客户端,拥有易于使用的 API,可在浏览器和 Node.js 环境中使用。它为 JavaScript 开发者提供了一个多功能工具。 Axios 与内置的 Fetch API 在几个方面有所不同,包括其对 HTTP 错...
    程式設計 發佈於2025-04-15
  • 如何使用node-mysql在單個查詢中執行多個SQL語句?
    如何使用node-mysql在單個查詢中執行多個SQL語句?
    在node-mysql node-mysql文檔最初出於安全原因最初禁用多個語句支持,因為它可能導致SQL注入攻擊。要啟用此功能,您需要在創建連接時將倍增設置設置為true: var connection = mysql.createconnection({{multipleStatement:...
    程式設計 發佈於2025-04-15
  • 永不遺忘防抖與節流,附Codepen可視化
    永不遺忘防抖與節流,附Codepen可視化
    这不仅是另一篇文章,试图解释如何在代码级别上工作,而是要记住和可视化概念的例证,以便您可以在工作中实际应用它们。 就个人而言,我经常发现自己忘记了辩论和节奏的概念,所以当有人要求我解释它们时,或者是否在采访中出现了问题 - 我只是眨眼?为了避免这种情况,我制作了一个简单的页面来帮助刷新我的记忆。如果...
    程式設計 發佈於2025-04-15
  • 為什麼儘管有效代碼,為什麼在PHP中捕獲輸入?
    為什麼儘管有效代碼,為什麼在PHP中捕獲輸入?
    在php ;?>" method="post">The intention is to capture the input from the text box and display it when the submit button is clicked.但是,輸出...
    程式設計 發佈於2025-04-15
  • CSS能否實現無if/else的條件邏輯?
    CSS能否實現無if/else的條件邏輯?
    1。 CSS類:通過利用HTML類,您可以為不同方案創建不同的樣式規則。例如,以下代碼基於類分配不同的背景位置: 2。 CSS預處理器(例如,sass): 像SASS這樣的預處理程序提供有條件的語句,可允許更複雜的條件: 3。 CSS自定義屬性(變量): CSS中的自定義屬性與變量相似,並在運...
    程式設計 發佈於2025-04-15
  • SQL Server 2012身份列值為何跳到1001?
    SQL Server 2012身份列值為何跳到1001?
    SQL Server Identity列的值突然跳至1001:SQL Server 2012中的說明在SQL Server 2012中,用戶遇到了一個有趣的問題,其中身份列值突然從一個序列列值跳到了1001個順序模式(E.G.,1,1,1,1,1,1,3)要了解這種現象背後的原因,讓我們深入研究...
    程式設計 發佈於2025-04-15
  • JavaScript中如何動態訪問全局變量?
    JavaScript中如何動態訪問全局變量?
    在JavaScript 一種方法是使用窗口對象存儲和檢索變量。通過引用全局範圍,可以使用其名稱動態訪問變量。 //一個腳本 var somevarname_10 = 20; //另一個腳本 window.all_vars = {}; window.all_vars ['somevarna...
    程式設計 發佈於2025-04-15
  • 如何從Google API中檢索最新的jQuery庫?
    如何從Google API中檢索最新的jQuery庫?
    從Google APIS 問題中提供的jQuery URL是版本1.2.6。對於檢索最新版本,以前有一種使用特定版本編號的替代方法,它是使用以下語法:獲取最新版本:未壓縮)While these legacy URLs still remain in use, it is recommended ...
    程式設計 發佈於2025-04-15
  • Python中何時用"try"而非"if"檢測變量值?
    Python中何時用"try"而非"if"檢測變量值?
    使用“ try“ vs.” if”來測試python 在python中的變量值,在某些情況下,您可能需要在處理之前檢查變量是否具有值。在使用“如果”或“ try”構建體之間決定。 “ if” constructs result = function() 如果結果: 對於結果: ...
    程式設計 發佈於2025-04-15
  • 在C#中如何高效重複字符串字符用於縮進?
    在C#中如何高效重複字符串字符用於縮進?
    在基於項目的深度下固定字符串時,重複一個字符串以進行凹痕,很方便有效地有一種有效的方法來返回字符串重複指定的次數的字符串。使用指定的次數。 constructor 這將返回字符串“ -----”。 字符串凹痕= new String(' - ',depth); console.W...
    程式設計 發佈於2025-04-15
  • 處理Java HashMap中的"GC Overhead Limit Exceeded"錯誤
    處理Java HashMap中的"GC Overhead Limit Exceeded"錯誤
    要解決此問題,可以考慮使用“ -XMX1024M”增加增加堆大小或使用“ -XX:-XX:-USEGCOVERHEADLIMITILIMIT”來禁用錯誤檢查。雖然第一種方法可以解決問題,但第二種方法可能會導致與堆相關的另一個OutofmemoryError。 ,而不是這些命令行參數,可以為小ha...
    程式設計 發佈於2025-04-15

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3