es6 Proxy代理

xiaoxiao2021-02-28  17

1.Proxy的实现 es6为开发者提供了一个新特性:Proxy,就是代理的意思。就好比如我们无法修改我们自己银行账户上的数据,需要代理给柜员,帮我们办理存钱或者取钱业务,而Proxy也是这样的一种机制。

var log = console.log.bind() // 定义一个对象person var person = {name:'小白'}; //创建一个代理对象pro,代理person对象的读写操作 var pro = new Proxy(person,{ get(target,property){ return "小黑" } }) log(pro.name) // "小黑"

Proxy代理过程中,get方法实现了拦截的作用,不管你读取什么属性,我都返回“小黑”。这就是代理Proxy的作用,将对象交给了Proxy代理,然后通过编写处理函数,来拦截目标对象的操作。

2.set方法

var bankAccount = {rmb:1000,dollar:0}; var banker = new Proxy(bankAccount,{ get(target,property){ if(target[property]>0){ return target[property] }else{ return "余额不足" } }, set(target,property,value){ if(!Number.isInteger(value)){ return "请设置正确的数值" }else{ target[property] = value } } }) log(banker.rmb) // 1000 log(banker.dollar) // 余额不足 banker.rmb = 500; log(banker.rmb) // 500 banker.dollar = "三万"; log(banker.dollar); // 请设置正确的数值 banker.dollar = 30000; log(banker.dollar); // 30000

get方法拦截了读写操作,set方法拦截了改写操作。

3.ownKeys()方法 ownKeys拦截操作,拦截过滤Object.ownKeys()对对象的属性的遍历。说白了就是限制你只能查看部分的属性。

var person1 = { name:'小白', age:24, zodizc:'dog' } var pro1 = new Proxy(person1,{ ownKeys(target){ return ['name','age'] //由于疏忽的缘故这里我写成了[name.age]从而导致报错 } }) log(Object.keys(person1)); //["name", "age", "zodizc"] log(Object.keys(pro1)) //["name", "age"]

通过ownKeys方法程序,不管你有多少属性,只会返回指定的那些,在这里也就是name和age。这里调用Object.keys(pro1),遍历的是被代理proxy对象,所以只能得到被过滤的后果。

4.has()方法 hsa()拦截操作:拦截key in object的操作,结果返回一个布尔值。

var person1 = { name:'小白', age:24, zodizc:'dog' } var pro2 = new Proxy(person1,{ has(target,property){ if(target[property] === undefined){ return false }else{ return true } } }) log("name" in pro2) // true log("height" in pro2)// false 其实就是判断代理对象pro2是否有这个属性

has()方法用于判断是否含有指定的键值对,有就返回true,没有就返回false。

5.apply()方法 除了对象类型的变量可以被代理,函数也是可以被代理的。如果被代理的变量是一个函数,那么还会支持一个拦截程序:apply调用。

var fn1 = function(){ log(11111) } var pro3 = new Proxy(fn1,{ apply(){ log(2222) } }) fn1() // 11111 pro3() // 2222

proxy本身是一个代理实例对象,因为代理的是一个函数fn1,所以可以直接调用pro3();当它当作函数调用的时候,就会被apply拦截,执行log(2222)。

6.Proxy.revocable()取消代理 取消代理可以使用Proxy.revocable()函数,它会返回一个对象,对象中含有一个proxy属性,他就是Proxy的代理实例对象。还有一个revoke属性,它是一个方法,用于取消代理。

//定义一个对象 var person1 = { name:'小白', age:24, zodizc:'dog' } //定义一个代理处理程序 var handle = { get(target,property){ return "小黑" } } //使用Proxy.revocable()进行代理 var obj = Proxy.revocable(person1,handle); var obj = Proxy.revocable(person1,{ get(target,property){ return "小黑" } }) log(obj.proxy.name) obj.revoke(); log(obj.proxy.name) // 报错

需要注意的是,Proxy.revocable()方法返回的结果时一个对象。 有一个proxy属性,它就是Proxy代理实例,还有一个属性revoke,它是一个方法,专用于取消代理。

我们使用object.proxy.name来读取name的属性,由于被代理拦截了,只能读取到“小黑”,接着我们调用revoke( )方法取消代理,然后再使用object.proxy.name的时候就会报错了,代理已经不存在了。

总结:ES6带了的Proxy代理机制,它提供了一些拦截操作:set、get、apply、has、ownKeys等,我们可以根据需求编写拦截程序,达到我们想要的效果;此外,还可以利用Proxy.revocable( )实现取消代理。

转载请注明原文地址: https://www.6miu.com/read-2599059.html

最新回复(0)