ES6之Proxy详解

一.什么是Proxy

   Proxy是es6新增的一个属性,用于修改某些操作的默认行为,可以理解为在目标对象外层设置一层“拦截”,外界如果想要访问目标对象,都必须先通过这层拦截,所以proxy提供了一种机制可以对外界的访问进行过滤和改写,用在这里proxy表示代理器的意思。

   Proxy通过使用一个代理对象来包装目标对象,并提供了一组钩子函数(也称为“陷阱”),这些钩子函数可以在代理对象上进行操作。当我们对代理对象进行操作时,本质上是在调用这些钩子函数。

二.Proxy用法

    在ES6中提供了Proxy构造函数,可以用这个构造函数生成Proxy实例

var proxy = new Proxy(target,handler);

在上述示例中, new Proxy()表示生成一个Proxy实例,target表示的是所要拦截的目标对象,handler是用来定制拦截行为,也是一个对象,需要向其中提供对应的处理函数,该函数将拦截对应的操作 。

三.常用Proxy属性用法

    3.1 get(target,prop,receiver)
  • 作用:用于拦截某个属性的读取操作
  • 参数:target:目标对象 ;prop:属性名;receiver:proxy实例本身(操作行为所针对的对象,改参数是可选的)
  • 示例
 var person ={
            name:"jack"
        };
        var proxy =new Proxy(person,{
            get: function(target,prop) {
                if(prop in target){
                   console.log(target[prop]);
                }
                else{
                   throw new ReferenceError("Prop name \"" + propKey + "\" does not exist.")
                }
            }
        })
        proxy.name//jack
        proxy.age//抛出一个错误
   3.2 set(target,prop,value,receiver)
  • 作用:用于拦截某个属性的赋值操作
  • 参数:target:目标对象;prop:属性名;value:属性值;receiver:Proxy实例本身(该参数可选)
  • 示例:
     var person ={
                name:'john'
            };
            var proxy =new Proxy(person,{
                set: function(target,prop,value){
                    if(prop==='age'){
                        if(value>200){
                            throw new RangeError('不符合范围')
                        }
                        else{
                            target[prop]=value;
                        }
                    }
                }
            })
            proxy.age=400//报错,不继续执行
            proxy.age=100//100
    
        3.3 apply(target,ctx,args) 
  • 作用:拦截函数的调用
  • 参数:target:目标对象;ctx:目标对象的上下文对象;args:目标对象的参数数组
  • 示例:
     var target= function(){return '目标对象';};
        var handler={
            apply:function(){
                return '代理对象';
            }
        };
        var p =new Proxy(target,handler);
        p();//代理对象
       3.4 has(target,key)
  • 作用:用来拦截HasProperty操作,判断对象是否具有某个属性
  • 参数:target:目标对象;key:需要查询的属性名
  • 示例:
     var handler={
            has(target,key){
                if(key[0]==='_'){
                    return false
                }
                return key in target;
            }
        };
      var target={_prop:'jack',prop:'john' };
      var proxy =new Proxy(target,handler)
    由于'_prop' in proxy中,所以返回结果为false,不会被in操作符发现
          3.5 construct(target,args,newTarget)
  • 作用:用于拦截new命令
  • 参数:target:目标对象;args:构造函数的参数对象;newTarget:创建实例对象时,new命令作用的构造函数
  • 注意:construct方法返回的必须是一个对象,否则会报错
  • 示例:
    var p =new Proxy(function(){},{
        construct: function(target,args){
            console.log('called'+args.join(','));
            return {value:args[0]*10}
        }
    });
    console.log((new p(1)).value);//called1;10
          3.6 deleteProperty(target,key)
  • 作用:拦截delete操作,如果这个方法抛出错误或者返回false,当前属性就无法被delete删除
  • 参数:target:目标对象;key:要删除的属性
  • 示例:
    var handler={
        deleteProperty(target,key){
            judge(key,'delete');
            delete targetp[key];
            return true;
        }
    };
    function judge(key,action){
        if(key[0]==='_'){
            throw new Error('删除属性错误')
        }
    }
    var target={_prop:'foo'};
    var proxy = new Proxy(target,handler);
    delete proxy._prop//报错,删除属性错误
           3.7 getPropertyOf(target)
  • 作用:拦截对代理对象原型链上属性的访问操作
  • 参数:target:目标对象
  • 示例:
    const target={};
    const proxy=new Proxy(target,{
        getPrototypeOf(target) {
            console.log('get prototype');
            return Object.getPrototypeOf(target)
        }
    });
    console.log(Object.getPrototypeOf(proxy));//get prototype
            3.8 setPrototypeOf(target,prototype)
  • 作用:拦截对代理对象原型链上属性的设置操作

  • 参数:target:目标对象;prototype:要设置的原型对象

  • 示例:

     const target ={}
        const proxy=new Proxy(target,{
            setPrototypeOf(target,prototype){
                console.log('set prototype');
                return Object.setPrototypeOf(target,prototype)
            }
        })
        const proto= {name:'jack'}
        Object.setPrototypeOf(proxy,proto)//set prototype
        console.log(proxy.name);//jack

     

 

    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值