ES6(六)proxy(代理)对象,一张“有灵魂”的拦截网

目录

前言

一、proxy

1、概述

2、语法

二、常用实例方法

1、get()---拦截读取

(1)就get()方法的第一二参数举例

 (2)下面针对get()方法的第三个参数举例

2、set()-----拦截赋值

(1)针对第一二三参数 举例

 (2)针对第四个参数 举例

三、结束语


前言

       proxy对象在有些官方文档里所阐述的尤其晦涩,但其实是专业术语太多,像targethandler等...(主要是很多资料的例子太繁杂了,一时间捋不清思路,建议大家冷静阅读,查资料,会事半功倍的,加油!
我们只要一一理解这些即可。它所代表的含义其实不难理解,今天小糖就来分享一下proxy~

一、proxy

1、概述

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

       通俗理解:在target对象之前有一层”拦截“,外界对target对象的访问必须经过一层”拦截“所                             以在这一层”拦截“上,可以对外界的访问操作进行修改或者过滤,而proxy就是
                         代理目标对象,调用handler拦截层里面的定制拦截行为实现更改操作

       可以这么理解:假设a是目标对象b是handler对象c是外界其他人,c想找a说话,a不在,c只能告诉b,等a回来了,b再告诉a。在这个过程中,b可以把c说的话进行修改和过滤。

2、语法

       let target = { /*目标对象的属性*/ };              //目标对象
       let handler = { /*用来定制拦截操作*/ };        //拦截层对象
       let proxy = new Proxy(target, handler);   //实例化

        Proxy 对象的所有用法,都是上面这种形式,不同的只是handler参数的写法(所要使用的功能不同,写法不同)。
        new Proxy()表示生成一个Proxy实例,作为代理对象
        target表示所要拦截的目标对象
        handler声明了代理 target 的指定行为,表示一个用来定制拦截行为的对象。

举个栗子~

       //写法1:间接写法

       {
           let a = { name: "凤求凰" };   //target目标对象
           
           console.log(a.name);   //未拦截时,结果是原来的  value


           let b = { get: function(target,prokey) {
               return  "李白";            //定制拦截行为,将 name 改为李白
           } 
        };

           
           //实例化一个proxy对象 调用 b(拦截层) 对 a(目标对象) 进行 拦截 与 修改

           let myProxy = new Proxy(a,b);  //代理对象实例化,参数是 target 和 handler
           
           console.log(myProxy.name);     //结果改变了
       }

结果验证: 在未实例化一个proxy对象时,结果与预先设置的value一样,实例化proxy对象并调用                   之后,结果改变了

 

二、常用实例方法

ES6 中的proxy目前提供了13种可代理操作拦截的行为,小糖今天只讲最常见的setget方法

1、get()---拦截读取

该方法可以接受三个参数,target(目标对象)、propkey(目标对象的属性名) 与 getReceiver它自身(可选可不选)

(1)就get()方法的第一二参数举例

声明一个target对象,访问一个对象自身不存在的属性时,返回的是undefind,但是我们可以拦截该行为并将该操作修改为error(抛出错误)

未拦截之前
 

let person = {
  name: "李白"
};
console.log(person.age);  //结果为undefind

 添加拦截后

{

let person = {
  name: "李白"
};

let proxy = new Proxy(person, {
  get: function(target, propKey) {
    if (propKey in target) {
      return target[propKey];
    } else {
      throw new ReferenceError("Prop name \"" + propKey + "\" does not exist.");
    }
  }
});
proxy.name // "李白"
proxy.age // 抛出一个错误

}

                                                拦截修改后,我们更改成抛出错误 

 (2)下面针对get()方法的第三个参数举例

前面说到,第三个参数是proxy本身,我们利用proxy提供的属性getReceiverproxy比较,验证

{
    let a = {};   //目标对象

    let myProxy = new Proxy(a, {
      get: function(target, key, receiver) {
        return receiver;
      }
    });
   if( myProxy.getReceiver === myProxy){
       console.log("true");
   }else{
       console.log("false");
   }

}

2、set()-----拦截赋值

该方法可以接受四个参数,target(目标对象)、key(目标对象的属性名) 、value(属性名)、getReceiver自身(可选可不选)

(1)针对第一二三参数 举例

假设目标对象的age属性,利用setage属性的属性值添加条件,保证age的属性值符合要求

{
    let a = {};      //目标对象
    let b = {
        set: function (target,key,value) {
            if(key === 'age'){
                if(value >200){
                    //抛出一个错误
                    throw new RangeError('The age seems invalid');
                }
            }
            //满足条件 直接保存值
            target[key] = value;
            return true;
        }
    }
    let myproxy = new Proxy(a, b);
    myproxy.age = 100;         //命名一个小于200的值,正常运行
    console.log(myproxy.age);  //正常运行

    myproxy.age = 300;         //命名一个大于200的值    
    console.log(myproxy.age);  //报错
}

结果

 

 (2)针对第四个参数 举例

利用proxy调用第四个参数判断是否与已知值全等

{
    let b = {
        function(target,key,value,receiver) {
            target[key] = receiver;
            return true;
        }
    };
    let myproxy = new Proxy({},b);
    myproxy.name = myproxy;   //将name属性赋值为myproxy

    if(myproxy.name === myproxy){ //判断是否为myproxy
       console.log("true");
   }else{
       console.log("false");
   }
}

结果

 

三、结束语

希望本篇文章可以帮到求知若渴的众多同学吖~
若能帮到 也欢迎
点赞、收藏、关注我,后续也会持续发布新文章,祝大家学有所成!
欢迎各位前端大佬留言讨论指教! 
小糖谢谢各位啦~❤  ❤  ❤  ❤

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值