es6(七)—— Proxy 和 Reflect


1: proxy

(1)定义

proxy 本身就是代理的意思,你可以理解为在目标对象之前架设一层“拦截”,外界对这个对象进行所有的操作,都需要经过这层拦截。因此提供了一种机制,可以对外界的访问进行过滤和改写。

(2)作用

proxy 可以对目标对象的读取、函数调用等操作进行拦截,然后进行操作处理。它不直接操作对象,而是像代理模式,通过对象的代理对象进行操作,在进行这些操作时,可以添加一些需要的额外操作,等同于在语言层面做出修改。

(3)使用方法
/**
 1. @target  要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)
 2. @handler 一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p 的行为。
*/
 const p = new Proxy(target, handler)
(4)所有方法简单说明
  1. get(target, propKey, receiver):拦截对象属性的读取,比如proxy.foo和proxy[‘foo’]。
  2. set(target, propKey, value, receiver):拦截对象属性的设置,比如proxy.foo = v或proxy[‘foo’] = v,返回一个布尔值。 has(target, propKey):拦截propKey in proxy的操作,返回一个布尔值。
  3. deleteProperty(target, propKey):拦截delete
  4. proxy[propKey]的操作,返回一个布尔值。
  5. ownKeys(target):拦截Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy)、for…in循环,返回一个数组。该方法返回目标对象所有自身的属性的属性名,而Object.keys()的返回结果仅包括目标对象自身的可遍历属性。
  6. getOwnPropertyDescriptor(target, propKey):拦截Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象。
  7. defineProperty(target, propKey, propDesc):拦截Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值。
  8. preventExtensions(target):拦截Object.preventExtensions(proxy),返回一个布尔值。
  9. getPrototypeOf(target):拦截Object.getPrototypeOf(proxy),返回一个对象。
  10. isExtensible(target):拦截Object.isExtensible(proxy),返回一个布尔值。
  11. setPrototypeOf(target, proto):拦截Object.setPrototypeOf(proxy, proto),返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。
  12. apply(target, object, args):拦截 Proxy 实例作为函数调用的操作,比如proxy(…args)、proxy.call(object, …args)、proxy.apply(…)。
  13. construct(target, args):拦截 Proxy 实例作为构造函数调用的操作,比如new proxy(…args)。
(5)简单应用
var proxy = new Proxy({}, {
  get: function(target, propKey) {
    return 35;
  }
});
proxy.name// 35
proxy.xxx// 35
proxy.yyy // 35
// 无论是proxy.xxx 的返回值都将是35,从根本上改变了proxy的返回值

2: Reflect

(1)定义:Reflect与 Object 类似,但是更易读,为操作对象提供了一种更优雅的方式。它的方法与 Proxy 是对应的。是 ECMA 国际标准化组织为了更好的获取目标对象的行为而创建的。
(2)作用:为了更好的获取目标对象的行为,对某些方法的返回结果进行了修改,使其更合理,并实现了使用函数的方式实现了 Object 的命令式操作。在使用对象的 Object.defineProperty(obj, name, {})时,如果出现异常的话,会抛出一个错误,需要使用try catch去捕获,但是使用 Reflect.defineProperty(obj, name, desc) 则会返回true/false。
(3)静态方法: Reflect对象一共有 13 个静态方法。

  1. Reflect.apply(target, thisArg, args)
  2. Reflect.construct(target, args)
  3. Reflect.get(target, name, receiver)
  4. Reflect.set(target, name, value, receiver)
  5. Reflect.defineProperty(target, name, desc)
  6. Reflect.deleteProperty(target, name)
  7. Reflect.has(target, name)
  8. Reflect.ownKeys(target)
  9. Reflect.isExtensible(target)
  10. Reflect.preventExtensions(target)
  11. Reflect.getOwnPropertyDescriptor(target, name)
  12. Reflect.getPrototypeOf(target)
  13. Reflect.setPrototypeOf(target,prototype)
    上面这些方法的作用,大部分与Object对象的同名方法的作用都是相同的,而且它与Proxy对象的方法是一一对应的。
    如果

3:Proxy 和 Reflect的组合使用就是vue3中的双向绑定原理,兴趣的可以了解一下

es6 proxy参考文档: https://es6.ruanyifeng.com/#docs/proxy

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值