ES6 Reflect 与 Proxy

Proxy 与 Reflect 是 ES6 为了操作对象引入的 API 。

1、Proxy 

Proxy 可以对目标对象的读取、函数调用等操作进行拦截,然后进行操作处理。它不直接操作对象,而是像代理模式,通过对象的代理对象进行操作,在进行这些操作时,可以添加一些需要的额外操作。
Proxy基本用法:

Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程。
Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。
Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”

let pro = new Proxy(target,handler);
其中 new Proxy相当于创建了一个Proxy实例,target为所要拦截的目标对象,handler也是一个对象,里面定义的是对拦截对象所要进行的拦截方法

<script type="text/javascript">
  //Proxy
  let target = {name:'rdb',pwd:123456}
  let handler = {
      get:function(target,propKey){
            return target[propKey];
      }
  }
  let pro = new Proxy(target,handler);
  console.log(pro.name,pro.pwd); //rdb 123456
</script>

Proxy常用的拦截方法

(1)get(target, propKey, receiver):拦截对象属性的读取,第一个参数为目标对象,第二个参数为属性名称,第三个属性为操作所针对的对象(可选参数)。

<script type="text/javascript">
  //Proxy
  let target = {name:'rdb',pwd:123456}
  let handler = {
      get:function(target, propKey, receiver){
            if(propKey in target){
                console.log("success");
            }else{
                console.log("false");
            }
          return Reflect.get(target, propKey, receiver);
      }
  }
  let pro = new Proxy(target,handler);
  console.log(pro.name,pro.pwd); //rdb 123456
</script>

(2)set(target, propKey, value, receiver):拦截对象属性的设置,第一个参数为目标对象,第二个参数为属性名,第三个参数为属性值,第四个参数为操作行为所针对的对象(可选参数)。

<script type="text/javascript">
  //Proxy
  let target = {name:'rdb',pwd:123456}
  let handler = {
      get:function(target, propKey, receiver){
            if(propKey in target){
                console.log("success");
            }else{
                console.log("false");
            }
          return Reflect.get(target, propKey, receiver);
      },
      set:function (target, propKey, value, receiver) {
          if(propKey=='pwd'){
              if(!Number.isInteger(value)){
                  throw new TypeError('The age is not an integer');
              }else{
                  console.log("set success");
              }
          }else{
              console.log("set success");
          }
          return Reflect.set(target, propKey, value, receiver);
      }
  }
  let pro = new Proxy(target,handler);
  console.log(pro.name,pro.pwd); //rdb 123456

    pro.name='jack';
    pro.pwd=123;
  console.log(pro.name,pro.pwd); //jack 123 //当pwd是字符串是会抛出异常


</script>

(3)has(target, propKey):用来拦截对象是否具有某个属性值的操作,第一个参数为目标对象,第二个参数为属性名

<script type="text/javascript">
  //Proxy
  let target = {name:'rdb',pwd:123456}
  let handler = {
      get:function(target, propKey, receiver){
            if(propKey in target){
                console.log("success");
            }else{
                console.log("false");
            }
          return Reflect.get(target, propKey, receiver);
      },
      set:function (target, propKey, value, receiver) {
          if(propKey=='pwd'){
              if(!Number.isInteger(value)){
                  throw new TypeError('The age is not an integer');
              }else{
                  console.log("set success");
              }
          }else{
              console.log("set success");
          }
          return Reflect.set(target, propKey, value, receiver);
      },
      has:function(target, propKey){
          console.log('handle has');
          return propKey in target;
      }
  }
  let pro = new Proxy(target,handler);
  console.log(pro.name,pro.pwd); //rdb 123456

    pro.name='jack';
    pro.pwd=123;
  console.log(pro.name,pro.pwd); //jack 123 //当pwd是字符串是会抛出异常

  console.log('name' in pro);//判断
  console.log('pwd' in pro);//判断


</script>

2、Reflect 

Reflect 可以用于获取目标对象的行为,它与 Object 类似,但是更易读,为操作对象提供了一种更优雅的方式。它的方法与 Proxy 是对应的

原文地址:https://www.cnblogs.com/jnba/p/12221498.html