美文网首页
ES6新特性——Proxy代理

ES6新特性——Proxy代理

作者: _hider | 来源:发表于2019-06-16 11:36 被阅读0次

    Proxy如其名, 它的作用是在对象和和对象的属性值之间设置一个代理,获取该对象的值或者设置该对象的值, 以及实例化等等多种操作, 都会被拦截住, 经过这一层我们可以统一处理,我们可以认为它就是“代理器” 。

    let obj = new Proxy(target, handler);
    

    Proxy是一个构造函数, 使用new Proxy创建代理器, 它的第一个参数target是要包装的目标对象Proxy。它可以是任何类型的对象,包括本机数组,函数或甚至另一个代理,第二个参数handler也为一个对象, 返回被包裹后的代理器。举个例子:

    //被代理的对象
    let item = {
        userName:'don',
        age:18
    }
    //代理对象
    let proxyItem = new Proxy(item, {
        get : function( target , prop ) {
            console.log("我要获取值了");
            return target[prop];
        },
        set : function( target, prop, value) {
            console.log("我要设置值了");
            target[prop] = value;
            return true
        }
    });
    obj.userName = 'alice'; // 我要设置值了
    console.log(obj.age) ; // 我要获取值了
    
    属性检验
    let product = {
        productPrice: 200
    };
    let obj = new Proxy(product, {
        set: function (target, key, value) {
            if(value<100){
                throw new RangeError('价格太低了');
            }else if(value>300){
                throw new RangeError('价格太高了');
            }
            target[key] = value;
            return true
        }
    });
    obj.productPrice = 301; // RangeError  价格太高了
    obj.productPrice = 99; // RangeError  价格太低了
    obj.productPrice = 120;
    

    要修改item的时候会进入代理对象的get或者set进行检验,来控制是否可以读取属性,如果不满足条件就抛出错误,只有验证通过了才设置到对象上。

    let product = {
        productPrice:200
    };
    let obj = new Proxy(product, {});
    obj.productPrice = 300;
    console.log(obj) // { productPrice:300 }
    console.log(product) // { productPrice:300 }
    

    如果没有给Proxy设置get或者set,这就相当于没有设置过这个代理。

    设置多个proxy
    let product = {
        productPrice:200
    };
    let productProxy1 = new Proxy(product, {
        set:function(target,key,value){
            if(value < 100){
                throw new RangeError("价格太低了")
            }
            target[key] = value;
            return true;
        }
    });
    
    let productProxy2 = new Proxy(product,{
        set:function(target,key,value){
            if(value>300){
                throw new RangeError("价格太高了")
            }
            target[key] = value;
            return true;
        }
    })
    productProxy1.productPrice = 102;
    productProxy2.productPrice = 14;
    console.log(product) //{ productPrice:14 }
    

    一个对象支持同时设置多个proxy,不同的proxy只对自己的验证条件有效。比如上例中的productProxy1,它会检验修改的productPrice是否小于100,修改完进入productProxy2验证,productProxy2只验证是否大于300,这时传入的14,满足productProxy2,验证通过。但是productProxy1之前的检验就失效了,所以多个proxy验证的时候要注意这个问题。

    第二个参数

    Proxy的第二个参数为一个对象, 对象的参数为以下的列表, Proxy提供了更多的接口 , 通过不同的参数, 我们可以截获代码的运行并重新处理。参考链接

    • handler.getPrototypeOf()
    • handler.setPrototypeOf()
    • handler.isExtensible()
    • handler.preventExtensions()
    • handler.getOwnPropertyDescriptor()
    • handler.defineProperty()
    • handler.has()
    • handler.get()
    • handler.set()
    • handler.deleteProperty()
    • handler.ownKeys()
    • handler.apply()
    • handler.construct()

    相关文章

      网友评论

          本文标题:ES6新特性——Proxy代理

          本文链接:https://www.haomeiwen.com/subject/zxpwfctx.html