”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 了解 Javascript 代理和 Reflect API

了解 Javascript 代理和 Reflect API

发布于2024-11-08
浏览:657

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]删除
最新教程 更多>
  • 如何保护我的网站源代码免遭未经授权的访问?
    如何保护我的网站源代码免遭未经授权的访问?
    保护源代码免遭未经授权的访问防止他人获取您的源代码可能是一项挑战。但是,您可以采取一些措施来阻止未经授权的复制。混淆技术保护代码的一种方法是通过混淆。这涉及将代码转换为可读性较差的格式。混淆工具,例如 http://code.google.com/p/minify/、http://refresh-s...
    编程 发布于2024-11-09
  • 如何在Python中确定整数的位数?
    如何在Python中确定整数的位数?
    在 Python 中确定整数中的位数长度在 Python 中,获取整数中的位数是一个简单的过程。该技术涉及使用 str() 函数将整数临时转换为字符串,然后使用 len() 函数确定字符串的长度。例如,如果要查找整数 123 中的位数,可以使用 str(123) 将其转换为字符串,结果为“123”。...
    编程 发布于2024-11-09
  • 超自然故事:来自世界各地的神话生物
    超自然故事:来自世界各地的神话生物
    https://pageexplorer.blogspot.com/2024/10/tales-of-supernatural-mythical.html 我希望您能查看我最新的博客文章!您的想法和反馈对我来说非常有价值,如果您能花点时间阅读并在评论中分享您的见解,我将不胜感激。无论是建设性的批评还...
    编程 发布于2024-11-09
  • Python 中的结构模式匹配
    Python 中的结构模式匹配
    结构模式匹配是Python中的一个强大功能,它允许您根据复杂数据的结构做出决策并从中提取所需的值。它提供了一种简洁、声明式的方式来表达条件逻辑,可以极大地提高代码的可读性和可维护性。在本文中,我们将探讨一些在 Python 中使用结构模式匹配的真实案例研究示例。 1。解析 API 响应 结构模式匹配...
    编程 发布于2024-11-09
  • 在 Laravel 11 中的支付处理编译时实现上下文绑定
    在 Laravel 11 中的支付处理编译时实现上下文绑定
    在我们之前的文章(如何在 Laravel 11 中添加和实现支付处理接口:硬编码绑定)中,我们通过硬编码 PaymentProcessorInterface 之间的绑定探索了设置支付处理器的第一步以及具体的实现,例如 StripePaymentProcessor。 虽然这种方法对于小型应用程序来说...
    编程 发布于2024-11-09
  • 如何解决“TypeError: Unsupported Operand Type(s) for -: \'str\' and \'int\'\”错误?
    如何解决“TypeError: Unsupported Operand Type(s) for -: \'str\' and \'int\'\”错误?
    "解决 TypeError: Unsupported Operand Type(s) for -: 'str' and 'int'"尝试编码时在 Python 中,遇到类似“TypeError: unsupported operand type(s...
    编程 发布于2024-11-09
  • 用于构建生成式人工智能应用程序的开源框架
    用于构建生成式人工智能应用程序的开源框架
    有许多令人惊叹的工具可以帮助构建生成式人工智能应用程序。但开始使用新工具需要时间学习和练习。 因此,我创建了一个存储库,其中包含用于构建生成人工智能应用程序的流行开源框架的示例。 这些示例还展示了如何将这些框架与 Amazon Bedrock 结合使用。 您可以在这里找到存储库: https://g...
    编程 发布于2024-11-09
  • 如何在不使用CSS“not”选择器的情况下选择特定元素之外的输入字段?
    如何在不使用CSS“not”选择器的情况下选择特定元素之外的输入字段?
    在没有“Not”的情况下导航CSS选择器:外部输入字段选择在CSS中,“not”选择器是一个受欢迎的功能这将允许用户从匹配条件中排除特定元素。目前,除非使用 JavaScript/jQuery,否则此功能在浏览器中不可用。例如,要选择类为“classname”的元素中的所有输入字段,CSS 代码将为...
    编程 发布于2024-11-09
  • CSS 形状:将文本环绕形状
    CSS 形状:将文本环绕形状
    介绍 CSS Shapes 是一个功能强大的工具,允许设计人员通过操纵 HTML 元素的形状来创建独特且具有视觉吸引力的布局。 CSS Shapes 最令人兴奋的功能之一是能够将文本环绕不同的形状。这允许更具创意和动态的文本布局,摆脱传统的矩形文本块。在本文中,我们将探讨 CSS ...
    编程 发布于2024-11-09
  • 如何维护禁用的选择元素中的输入字段值?
    如何维护禁用的选择元素中的输入字段值?
    在禁用的选择元素中维护输入字段值防止用户修改 表单字段,同时确保提交其值禁用选择元素和选项一种方法是禁用选择元素及其选项。这会阻止用户与元素交互,从而创建只读效果。但是,它也会阻止提交该值。在提交表单之前启用元素要解决此问题,请在提交表单之前禁用所有禁用的下拉菜单。这可以通过 JavaScript...
    编程 发布于2024-11-09
  • 如何确定 C++ 中动态分配数组的大小?
    如何确定 C++ 中动态分配数组的大小?
    在 C 中动态分配后确定数组大小 在 C 中,使用 new 运算符动态分配的数组本质上不会以编程方式公开其大小。这个问题源于这样的观察:delete[] 必须知道分配的数组的大小才能有效地释放内存。为什么没有内置函数来获取数组大小?与在堆栈上声明的数组不同,其大小可以使用 sizeof() 确定,动...
    编程 发布于2024-11-09
  • 解决 PHP 中的命名空间问题:为什么找不到类?
    解决 PHP 中的命名空间问题:为什么找不到类?
    解决 PHP 自动加载的命名空间问题在 PHP 中使用命名空间和自动加载机制时,经常会遇到无法找到所需类的错误。让我们探讨一下这个错误背后的原因并提供解决方案。如提供的代码片段所示,出现错误“Class 'Class1' not found”是因为 Class1 类未在全局范围内定义...
    编程 发布于2024-11-09
  • 如何轻松将 JavaScript 数组转换为逗号分隔列表?
    如何轻松将 JavaScript 数组转换为逗号分隔列表?
    提升 JavaScript:轻松将数组转换为逗号分隔列表在 JavaScript 中处理数组时,将它们转换为可读格式像逗号分隔的列表通常是一项常见任务。有一种巧妙的方法可以轻松实现此目的,而不是诉诸手动字符串连接。Array.prototype.join() 方法介绍数组。 prototype.jo...
    编程 发布于2024-11-09
  • 如何在 Socket.IO 中阻止发送方接收响应?
    如何在 Socket.IO 中阻止发送方接收响应?
    如何在 Socket.IO 中向除发送者之外的所有客户端发送响应?Socket.IO 提供了一系列的通信方法客户端和服务器。要将消息发送到所有客户端,可以使用 io.sockets.emit('response', data);。但是,当您需要排除发送客户端接收响应时,这种方法就不够...
    编程 发布于2024-11-09
  • 如何防止 Pandas 在保存 CSV 时添加索引列?
    如何防止 Pandas 在保存 CSV 时添加索引列?
    避免使用 Pandas 保存的 CSV 中的索引列使用 Pandas 进行修改后保存 csv 文件时,默认行为是包含索引列。为了避免这种情况,可以在使用 to_csv() 方法时将索引参数设置为 False。为了详细说明,请考虑以下命令序列:pd.read_csv('C:/Path/to/file....
    编程 发布于2024-11-09

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3