proxy的实现(代理)

29.proxy的实现  (代理)
get方法 

//定义一个对象person
var person = {"name":"张三”};
//创建一个代理对象pro, 代理person的读写操作
var pro = new
proxy (person,{
get :function( target ,property){
return ”李四”
}
});
pro. name;//李四

先定义一个对象,含有name属性,值为“张三”,创建一个代理对象pro,对象person的操作都交给代理对象pro,看最后一句代码,如果你要读取person对象的name属性,就要用pro.name,而不是person的name。我们看到的结果是:“李四“而不是person对象重点张三,因为代理过程中,get方法实现了拦截的作用,不管你读取什么属性,我都返回”李四“。
        这就是代理Proxy的作用,将一个对象交给了Proxy代理,然后通过编写处理函数,来拦截目标对象的操作。上面的案例,你可以理解为,person对象的name属性值不想被别人知道是“张三“,就设置了一个代理,让别人读取的时候,只获取到”李四“。
set方法
而上面提到的“编写处理函数“,get方法就是其中一个,除了get方法以外,还有一个很常用的是:set方法,它用于拦截对对象的写操作。
        我们来结合银行的例子,来用get方法和set方法的实现,这段代码有点长,但是注释很详细,注意看代码注释:

//定义一个对象,含有RMB和dollar属性值
var bankAccount = { " RMB" :1000, "dollar":0};
//创建一个Proxy代理实例
var banker = new Proxy( bankAccount,{
//编写get处理程序
get:function(target, property){
//判断余额是否大于0
if (target[property] > 0){
//有余额,就返回余额值
return target[property];
}else{
//没钱 了
return ”余额不足”;
}
},
//编写set处理程字
set:function( target ,property,value){
//存入的数额必须是一个数字类型
if ( ! Number .isInteger(value)){
return"请设置正确的数值";

}

//修改属性的值.

target[property] = value ;
});
banker . RMB ;
//结果: 1000
banker . dollar;
//结果:余额不足
//修改dollar属 性的值,值是字符串类型
banker .dollar = "五百”;
banker . dollar;
//结果:余额不足
//修改dollar属性的值,值是数字类型
banker .dollar = 500;
banker . dollar;
//结果: 500

几乎每一句代码都有注释,这段代码对应的故事情节是这样的:老王有的银行账户里面有一些存款,其中人民币1000元,美元0元。

var bankAccount = { " RMB":1000," dollar":0};

 有一天,他来到银行柜台前,找到一个叫banker的工作人员,取款之前看看账户里面还有多少钱,然后工作人员banker开始帮他操作(也就是代理)。

banker . RMB ;
//结果: 1000
banker. dollar;
//结果:余额不足

 
banker告诉他:“您账户里面有人民币1000元,可以取款的,但美元余额不足“。
 
接着,老王不打算取款了,打算存500美元。
在填写存款单据的时候,把500不小心写成了“五百“,banker告诫老王:”这样是写不行的,一定要写阿拉伯数字,这样写银行无法帮您存款的“。结果存款失败,账户里面的美元还是0元。

banker .dollar =“五百";
banker .dollar;
//结果:余额不足

 没关系,马上改过来,把“五百“改成500。

banker. dollar = 500 ;
banker . dollar ;
//结果: 500

存款成功,账户里面的美元已有500元。
        故事的整个经过就是这样,有了Proxy代理(银行工作人员bank),帮助老王完成查看银行存款和取款的操作(代理),避免了一些误操作。
        get方法拦截了读取操作,set方法拦截了改写操作。Proxy除了支持以上拦截程序,还支持一系列的拦截函数
30.proxy.revocable方法   取消代理
如果创建了代理之后又想取消代理的话,我们可以用Proxy.revocable( )(可废止的,可撤回的;)函数来实现,它会返回一个对象,对象中含有一个proxy属性,它就是Proxy的代理实例对象;还有一个revoke属性,
它是一个方法,用于取消代理。

//定义一个对象
let person:
{"name":"张三” };
//定义一个代理处理程序
let handLe = {
get:function( target ,prop){
return "李四";
}
};
//使用Proxy.revocable( )进行代理
let object = Proxy . revocable(person ,handle);
object. proxy . name;//结果:李四
//调用返回对象object的revoke方法,取消代理
object. revoke();
object . proxy . name;//报错,代理被取消

 这个案例大家要注意的是Proxy.revocable( )方法返回的结果,它是一个对象,在控制台打印出来后的结果是:Object{ proxy:Object , revoke:function(){....} }。有一个proxy属性,
它就是Proxy代理实例,还有一个属性revoke,它是一个方法,专用于取消代理。我们使用object.proxy.name来读取name的属性,由于被代理拦截了,只能读取到“李四”,接着我们调用revoke( )方法取消代理,
然后再使用object.proxy.name的时候就会报错了,代理已经不存在了。

  

posted @ 2020-08-02 16:39  Web前端全栈-小高  阅读(885)  评论(0)    收藏  举报