ES6 中的 Proxy 用法详解
在 Javascript 的世界中,除了原生的对象、数组以外,我们经常会用到一些“特殊”的对象,比如像 JSON、Map、Set 等等。它们都有着各自不同的特性,这些特性是我们在编写程序时可以大大提高效率的优势。在 ES6 中,我们又引入了一个新的特殊对象:Proxy。那么在什么情况下我们会用到 Proxy 呢?Proxy 又能做些什么事情呢?本文将对这些问题进行详细的解答。
- 什么是 Proxy?
Proxy 主要是用来增强 Object 对象的能力,它是一个对象的包装器,用来监视和修改某些操作,例如属性访问、赋值、函数调用等等。在 ES6 中,我们可以通过 Proxy 来代理包含各种属性元素的对象,从而实现对这些属性进行拦截、过滤或直接修改的效果。Proxy 可以理解为一种拦截器,它能够拦截所有对被代理的对象的访问,并做出一些响应。
- Proxy 的基本语法
在 ES6 中,创建 Proxy 对象的语法如下:
-- -------------------- ---- ------- --- ----------- - ----- --- --- ------- - - ---- ---------------- --------- - -------------------- ------------- ------ ---------------- -- ---- ---------------- --------- ------ - -------------------- ----------- -- ---------- ---------------- - ----- - - --- ----- - --- ------------------ --------
在上面的代码中,我们先创建了一个普通的对象 proxyTarget ,然后通过创建一个 handler 对象来为其设置代理,最终通过创建一个 Proxy 对象,将原始对象和代理处理器进行关联。
- Proxy 支持的各种拦截操作
在创建 Proxy 对象时,我们可以为其设置各种拦截操作,下面是 Proxy 支持的各种拦截操作:
3.1 get()
当我们访问代理对象的一个属性时,就会触发 handler 中的 get() 方法。get() 方法有三个参数:
- target:被代理对象。
- property:被访问的属性。
- receiver:代理对象。
下面是一段示例代码:
-- -------------------- ---- ------- --- ------ - ----- --- --- ------- - - ---- ---------------- --------- --------- - -------------------- ------------- ------ ------------------- --------- --------- - - --- ----- - --- ------------- -------- ----------------------
输出结果:
getting age 18
3.2 set()
当我们设置代理对象的一个属性时,就会触发 handler 中的 set() 方法。set() 方法有四个参数:
- target:被代理对象。
- property:被访问的属性。
- value:要被设置的值。
- receiver:代理对象。
下面是一段示例代码:
-- -------------------- ---- ------- --- ------ - ----- --- --- ------- - - ---- ---------------- --------- ------ --------- - -------------------- ----------- -- ---------- ------ ------------------- --------- ------ --------- - - --- ----- - --- ------------- -------- --------- - --
输出结果:
setting age to 20
3.3 has()
当我们使用 in 操作符检查一个属性是否存在于代理对象中时,会触发 handler 中的 has() 方法。has() 方法有两个参数:
- target:被代理对象。
- property:被检查的属性。
下面是一段示例代码:
-- -------------------- ---- ------- --- ------ - ----- --- --- ------- - - ---- ---------------- --------- - --------------------- --- -------- ------------- ------ ------------------- --------- - - --- ----- - --- ------------- -------- ----------------- -- ------
输出结果:
checking has property age true
3.4 deleteProperty()
当我们使用 delete 操作符删除代理对象的一个属性时,会触发 handler 中的 deleteProperty() 方法。deleteProperty() 方法有两个参数:
- target:被代理对象。
- property:被删除的属性。
下面是一段示例代码:
-- -------------------- ---- ------- --- ------ - ----- --- --- ------- - - --------------- ---------------- --------- - --------------------- -------- ------------- ------ ------------------------------ --------- - - --- ----- - --- ------------- -------- ------ ---------
输出结果:
deleting property age
3.5 apply()
当我们对代理对象进行函数调用时,会触发 handler 中的 apply() 方法。apply() 方法有三个参数:
- target:被代理函数。
- thisArg:被代理函数的上下文。
- argumentsList:被代理函数的参数列表。
下面是一段示例代码:
-- -------------------- ---- ------- --- ------ - ----------- -- - ------ - - - - --- ------- - - ------ ---------------- -------- -------------- - -------------------- -------- ---- ----- ------------------ ------ --------------------- -------- -------------- - - --- ----- - --- ------------- -------- -------------------- ---
输出结果:
calling function with args: 1,2 3
3.6 construct()
当我们使用 new 关键字来构造一个代理对象时,会触发 handler 中的 construct() 方法。construct() 方法有三个参数:
- target:被代理函数。
- argumentsList:构造函数的参数列表。
- receiver:代理对象。
下面是一段示例代码:
-- -------------------- ---- ------- --- ------ - ----------- -- - ------ - - ------ - - - --- ------- - - ---------- ---------------- -------------- --------- - ------------------------- ---- ----- ------------------ ------ ------------------------- -------------- --------- - - --- ----- - --- ------------- -------- --- -------- - --- -------- -- ----------------------- -----------
输出结果:
constructing with args: 1,2 1 2
- 总结
Proxy 可以在代码中灵活地添加逻辑,从而使我们的应用程序更加完善和强大。它可以帮助我们在对象、数组、函数等数据类型上添加额外的拦截器,以实现更精细化的控制。但需要注意的是,在使用 Proxy 时,我们需要小心处理数据的安全性和可靠性,避免因为激进的拦截操作而导致系统出现 bug 或异常情况。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/645cedb9968c7c53b0f75493