ECMAScript 6入门Proxy与Reflect(上)

ByteZenithMaster
• 阅读 1496

Proxy与Reflect

学习es6的新语法糖既能学习到新东西,又能使得自己的代码更加优雅,逼格更高,爽
proxy与Reflect之间的运用就是Reflect对对象的操作触发Proxy的拦截

  • Proxy是对对象进行代理,通过proxy生成的对象间接操作原本对象,最常见的就是get与set;语法形式var proxy = new Proxy(target, handler); target是需要操作的对象,而handler是包含操作target对象的一些方法的对象
  • Reflect是能够更加优雅的使用Object的相关方法

学习API

  • get

proxy: get(target, propKey, receiver)=>依次为目标对象、属性名和 proxy 实例本身(严格地说,是操作行为所针对的对象),其中最后一个参数可选。

let obj = {
    a: 'foo',
    b: 'Proxy',
    foo: ''
 }
let proxy = new Proxy(obj, {
    get (target, proKey, receive) {
      console.log(target === obj)     //true
      return '当对proxy进行取值操作时会触发这个get函数'
      
    }
 })

ps:proxytarget进行了代理,target就是obj对象,receive用于规定this到底指向哪个对象,

proxy.foo   //当对proxy进行取值操作时会触发这个get函数

上面这种情况并没有改变this的,所以console.log(receive === proxy) //true
Reflect也有get方法:Reflect.get(target, prokey, receive)

Reflect.get(proxy, 'foo') //同上没有this的指向
let newobj = {
    foo: 'this指向将改变'
}
Reflect.get(proxy, 'foo', newobj)  //foo = console.log(receive === proxy)  //true

所以对Reflect.get的第三个参数进行赋值将带入带proxy的get的第三个参数中

  • set

与get类似,这个是赋值时会触发set方法
proxy: set(target, propKey, value, receiver)

  let obj = {}
  let newobj = {
    a: '123'
  }
  let proxy = new Proxy(obj, {
    set (target, proKey, value, receive) {
      return target[proKey] = `当对proxy进行赋值操作时会触发这个set函数${value}`
      
    }
  })
  proxy.a = 666      //receive === proxy  true
  Reflect.set(proxy, 'a', 888)          //receive === proxy  true
  Reflect.set(proxy, 'a', 888, newobj)  //receive === newobj  true
  • apply

proxy的apply:apply(target, object, args)

  let twice = {
    apply (target, ctx, args) {
      console.log(ctx)    //undefined
      return Reflect.apply(...arguments);
    }
  }
  function sum (left, right) {
    this.num = 888  /如果ctx没有传入或者传入null,则会进行window.num = 888的赋值
    return left + right + this.nm
  }
  let obj = {
   nm: 666
  }
  var proxy = new Proxy(sum, twice);
  console.log(proxy(1, 2)) // 6
  console.log(proxy.apply(obj, [7, 8]))  //ctx则为obj,并改变return

执行流程:proxy触发函数调用,执行apply的方法,将参数自动带入,target就是sum函数,ctx没有传入为undefined,args1, 2,接下来将全部参数带入执行Reflect.apply

  • has

has比较简单,是对对象进行in运算,判断该属性是否存在对象中,可以是自身也可以是原型链上,不管是否可遍历

  • construct

在构造函数new时触发,

  var p = new Proxy(function () {}, {
    construct: function(target, args, newTarget) {
      console.log('called: ' + args.join(', '));
      console.log(newTarget === p)
      return { value: args[0] * 10 };
    }
  });

  console.log((new p(1)).value)
  //等价于下面,Reflect.construct(target, args), args必须是数组
  console.log(Reflect.construct(p, [1]))
  • ownKeys

返回对象中自身的所有属性,当然具体还是取决于return 什么内容;

触发条件:
Object.getOwnPropertyNames()
Object.getOwnPropertySymbols()
Object.keys()
for...in循环
let target = {
  a: 1,
  b: 2,
  c: 3,
  [Symbol.for('secret')]: '4',
};

Object.defineProperty(target, 'key', {
  enumerable: false,
  configurable: true,
  writable: true,
  value: 'static'
});

let handler = {
  ownKeys(target) {
    return ['a', 'd', Symbol.for('secret'), 'key'];
  }
};

let proxy = new Proxy(target, handler);
console.log(Object.keys(proxy))    //自动过滤symbol,不存在的属性,不可遍历的属性
console.log(Reflect.ownKeys(proxy)) //返回handler中return的值
点赞
收藏
评论区
推荐文章
Souleigh ✨ Souleigh ✨
4年前
Vue3.0 高频出现的几道面试题
1.Vue3.0性能提升主要是通过哪几方面体现的?1.响应式系统提升vue2在初始化的时候,对data中的每个属性使用definepropery调用getter和setter使之变为响应式对象。如果属性值为对象,还会递归调用defineproperty使之变为响应式对象。vue3使用proxy对象重写响应式。proxy的性能本来比def
Easter79 Easter79
3年前
Vue 3 深入响应性原理
深入响应性原理终于到了讲解我们Vue的响应式原理,前面我们已经讲解了Map,WeakMap,Set,WeakSet,Proxy,Reflect这几个知识点。那么接下来思考下到底什么是响应式,就比如我们做一个公司的官网,然后要求必须兼容手机端,ipad端,电脑端,内容屏幕大小变化而变化,这些就需要依赖Ja
Wesley13 Wesley13
3年前
java反射
packagecom.reflect;importjava.lang.reflect.InvocationTargetException;/\\\反射学习\反射的功能就是类、对象,可以通过反射获取里面的方法、属性的功能\@authorAdministrator\\/public
凯特林 凯特林
4年前
Vue3.0 高频出现的几道面试题
1、Vue3.0性能提升主要是通过哪几方面体现的?1.响应式系统提升vue2在初始化的时候,对data中的每个属性使用definepropery调用getter和setter使之变为响应式对象。如果属性值为对象,还会递归调用defineproperty使之变为响应式对象。vue3使用proxy对象重写响应式。proxy的性能本来比defineprope
Wesley13 Wesley13
3年前
java技术学习路线(自用)
一:常见模式与工具    1.常用设计模式:                 1.1.Proxy代理模式:指客户端并不直接调用实际的对象,而是通过调用代理,来间接的调用实际的对象。详见https://www.cnblogs.com/qifengshi/p/6566752.html       
Stella981 Stella981
3年前
Apache Https 代理Tomcat服务
本文的目的实现使用Apache服务器将https请求代理转发到后台tomcat服务上。1、准备1.安装apachehttpserver2.0以上版本,并安装mod\_rewrite,mod\_ssl,mod\_proxy,proxy\_ftp\_module,proxy\_http\_module模块。2.安装cryp
Wesley13 Wesley13
3年前
Java 动态代理实践AOP
大家都知道Spring中AOP是通过Java动态代理实现的,今天就来简单学习下demo。Java动态代理主要有两个核心类,InvocationHandler和Proxy。/{@codeInvocationHandler}istheinterfaceimplementedbythe<iinvo
Wesley13 Wesley13
3年前
ES6入门系列
  Reflect  是ES6为了操作对象而提供的新的API,目的是:1.将Object上一些明显属于语言内部的方法,比如Object.defineProperty 放到Reflect对象上现阶段某些方法同时在Object , Reflect上部署, 未来的新方法将只在Reflect对象上部署,也就是说从Reflect对
Wesley13 Wesley13
3年前
JDK动态代理的简单实现
1\.先理一下动态代理实现的思路:    实现功能:自己定义一个类Proxy,通过Proxy的静态方法newProxyInstance(Class<Tintface,InvocationHandlerh)返回代理对象, intface:被代理类的接口对象, h:InvocationHandler的实例对象    1).声明一段动
Stella981 Stella981
3年前
Dubbo之ProxyFactory
概述在分析服务暴露和服务引用的都提到ProxyFactory,它是Dubbo的代理工厂,只定义了两个方法。getInvoker,暴露服务时调用,将ref(真正的服务实现类)转化为InvokergetProxy,引用服务时调用,将Invoker对象转化为proxy代理对象InvokerInvoker是
服务网格自动故障检测及流量切换方案
随着云原生技术的发展,越来越多的应用采用容器,微服务技术,以istio为代表的服务网格就是其中最广泛使用的一种。它在业务容器创建时,自动向业务服务的pod中注入proxy容器边车,将流入和流出业务容器的网络流量全部劫持到proxy容器,经由proxy容器处理后再进行下一步转发。