ES6 中的 Proxy 用法详解

阅读时长 7 分钟读完

ES6 中的 Proxy 用法详解

在 Javascript 的世界中,除了原生的对象、数组以外,我们经常会用到一些“特殊”的对象,比如像 JSON、Map、Set 等等。它们都有着各自不同的特性,这些特性是我们在编写程序时可以大大提高效率的优势。在 ES6 中,我们又引入了一个新的特殊对象:Proxy。那么在什么情况下我们会用到 Proxy 呢?Proxy 又能做些什么事情呢?本文将对这些问题进行详细的解答。

  1. 什么是 Proxy?

Proxy 主要是用来增强 Object 对象的能力,它是一个对象的包装器,用来监视和修改某些操作,例如属性访问、赋值、函数调用等等。在 ES6 中,我们可以通过 Proxy 来代理包含各种属性元素的对象,从而实现对这些属性进行拦截、过滤或直接修改的效果。Proxy 可以理解为一种拦截器,它能够拦截所有对被代理的对象的访问,并做出一些响应。

  1. Proxy 的基本语法

在 ES6 中,创建 Proxy 对象的语法如下:

-- -------------------- ---- -------
--- ----------- - ----- ---

--- ------- - -
    ---- ---------------- --------- -
        -------------------- -------------
        ------ ----------------
    --
    ---- ---------------- --------- ------ -
        -------------------- ----------- -- ----------
        ---------------- - -----
    -
-

--- ----- - --- ------------------ --------

在上面的代码中,我们先创建了一个普通的对象 proxyTarget ,然后通过创建一个 handler 对象来为其设置代理,最终通过创建一个 Proxy 对象,将原始对象和代理处理器进行关联。

  1. Proxy 支持的各种拦截操作

在创建 Proxy 对象时,我们可以为其设置各种拦截操作,下面是 Proxy 支持的各种拦截操作:

3.1 get()

当我们访问代理对象的一个属性时,就会触发 handler 中的 get() 方法。get() 方法有三个参数:

  • target:被代理对象。
  • property:被访问的属性。
  • receiver:代理对象。

下面是一段示例代码:

-- -------------------- ---- -------
--- ------ - ----- ---
--- ------- - -
    ---- ---------------- --------- --------- -
        -------------------- -------------
        ------ ------------------- --------- ---------
    -
-
--- ----- - --- ------------- --------

----------------------

输出结果:

3.2 set()

当我们设置代理对象的一个属性时,就会触发 handler 中的 set() 方法。set() 方法有四个参数:

  • target:被代理对象。
  • property:被访问的属性。
  • value:要被设置的值。
  • receiver:代理对象。

下面是一段示例代码:

-- -------------------- ---- -------
--- ------ - ----- ---
--- ------- - -
    ---- ---------------- --------- ------ --------- -
        -------------------- ----------- -- ----------
        ------ ------------------- --------- ------ ---------
    -
-
--- ----- - --- ------------- --------
--------- - --

输出结果:

3.3 has()

当我们使用 in 操作符检查一个属性是否存在于代理对象中时,会触发 handler 中的 has() 方法。has() 方法有两个参数:

  • target:被代理对象。
  • property:被检查的属性。

下面是一段示例代码:

-- -------------------- ---- -------
--- ------ - ----- ---
--- ------- - -
    ---- ---------------- --------- -
        --------------------- --- -------- -------------
        ------ ------------------- ---------
    -
-
--- ----- - --- ------------- --------

----------------- -- ------

输出结果:

3.4 deleteProperty()

当我们使用 delete 操作符删除代理对象的一个属性时,会触发 handler 中的 deleteProperty() 方法。deleteProperty() 方法有两个参数:

  • target:被代理对象。
  • property:被删除的属性。

下面是一段示例代码:

-- -------------------- ---- -------
--- ------ - ----- ---
--- ------- - -
    --------------- ---------------- --------- -
        --------------------- -------- -------------
        ------ ------------------------------ ---------
    -
-
--- ----- - --- ------------- --------

------ ---------

输出结果:

3.5 apply()

当我们对代理对象进行函数调用时,会触发 handler 中的 apply() 方法。apply() 方法有三个参数:

  • target:被代理函数。
  • thisArg:被代理函数的上下文。
  • argumentsList:被代理函数的参数列表。

下面是一段示例代码:

-- -------------------- ---- -------
--- ------ - ----------- -- -
    ------ - - -
-
--- ------- - -
    ------ ---------------- -------- -------------- -
        -------------------- -------- ---- ----- ------------------
        ------ --------------------- -------- --------------
    -
-
--- ----- - --- ------------- --------

-------------------- ---

输出结果:

3.6 construct()

当我们使用 new 关键字来构造一个代理对象时,会触发 handler 中的 construct() 方法。construct() 方法有三个参数:

  • target:被代理函数。
  • argumentsList:构造函数的参数列表。
  • receiver:代理对象。

下面是一段示例代码:

-- -------------------- ---- -------
--- ------ - ----------- -- -
    ------ - -
    ------ - -
-
--- ------- - -
    ---------- ---------------- -------------- --------- -
        ------------------------- ---- ----- ------------------
        ------ ------------------------- -------------- ---------
    -
-
--- ----- - --- ------------- --------

--- -------- - --- -------- --

----------------------- -----------

输出结果:

  1. 总结

Proxy 可以在代码中灵活地添加逻辑,从而使我们的应用程序更加完善和强大。它可以帮助我们在对象、数组、函数等数据类型上添加额外的拦截器,以实现更精细化的控制。但需要注意的是,在使用 Proxy 时,我们需要小心处理数据的安全性和可靠性,避免因为激进的拦截操作而导致系统出现 bug 或异常情况。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/645cedb9968c7c53b0f75493

纠错
反馈