ES6新特性——Proxy代理

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代理)