ES9 中的 Proxy 对象和 Reflect 对象详解

阅读时长 6 分钟读完

在前端开发中,经常使用一些 JavaScript 的内置对象,如 ArrayObjectMath 等等。但是 ES9 为我们引入了 Proxy 对象和 Reflect 对象,它们的作用是什么呢?我们来详细了解一下。

Proxy

Proxy 对象是 ES9 新增的一个构造函数,它允许你创建一个代理对象,用来拦截对目标对象的访问和操作。

创建 Proxy

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

上面代码中,handler 对象是一个拦截器对象,它定义了 getset 方法用来拦截对 target 对象的读取和设置操作。我们通过 new Proxy 创建了一个代理对象 proxy,当我们利用 proxy 对象操作 target 对象时,会被拦截器对象所拦截,并执行对应的拦截操作。

拦截器方法

Proxy 对象提供了以下的拦截器方法:

  • getPrototypeOf(target) — 在 Object.getPrototypeOf() 中拦截获取对象的原型方法。
  • setPrototypeOf(target, proto) — 在 Object.setPrototypeOf() 中拦截修改对象原型的操作。
  • isExtensible(target) — 在 Object.isExtensible() 中拦截对象是否可以扩展的操作。
  • preventExtensions(target) — 在 Object.preventExtensions() 中拦截阻止对象扩展的操作。
  • get(target, prop, receiver) — 在读取对象属性值时拦截。
  • set(target, prop, value, receiver) — 在设置对象属性值时拦截。
  • has(target, prop) — 对 in 操作符拦截。
  • deleteProperty(target, prop) — 在删除对象属性时拦截。
  • defineProperty(target, prop, descriptor) — 在定义对象属性时拦截。
  • enumerate(target) — 在枚举对象属性时拦截。
  • ownKeys(target) — 拦截 Object.keysObject.getOwnPropertyNamesObject.getOwnPropertySymbols
  • apply(target, thisArg, argumentsList) — 在函数调用时拦截。
  • construct(target, argumentsList, newTarget) — 在使用 new 关键字创建实例对象时拦截。

Proxy 示例

我们通过以下的代码来演示 Proxy 的使用:

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

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

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

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

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

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

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

上面示例中,handler.set 拦截器方法检查了设置到数组的属性值的类型和范围,当条件不符时,会拦截操作并返回 false,反之则将值设置到数组中。

Reflect

Reflect 是 ES9 中的另一个内置对象,它提供一组方法用来操作对象,这些方法与 Proxy 对象拦截器方法的同名方法一样。

Reflect 和 Proxy

  • Proxy 拦截器方法与 Reflect 同名方法一样。
  • Reflect 对象的同名方法可以在 Proxy 拦截器方法中调用,以保持操作的原始行为。

Reflect 示例

通过以下的代码来演示 Reflect 对象的使用:

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

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

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

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

上面的示例中,我们通过 Reflect.getReflect.setReflect.deletePropertyReflect.defineProperty 方法来操作对象 apple

总结

在本文中,我们了解了 ES9 中的 Proxy 和 Reflect 对象。通过 Proxy 对象,我们可以为对象设置拦截器方法,从而拦截读写操作、删除操作等。而 Reflect 对象提供一组方法去操作对象,这些方法可以在 Proxy 对象拦截器方法中被调用。这些对象的使用能够帮助我们解决一些开发中的问题。

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

纠错
反馈