ES给开发者提供了一个新特性:Proxy,就是代理的意思。也就是我们这一节要介绍的知识点。

以前,ATM还没有那么流行的时候(暴露年纪),我们去银行存款或者取款的时候,需要在柜台前排队,等柜台工作人员帮我们办理业务,这也是一种代理,我们自己无法修改我们银行账户上的数据,需要代理给柜员,帮我们办理存钱或者取现业务,而Proxy也是这样的一种机制。

Proxy的实现

我们先来看看Proxy的实现:

    //定义一个对象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除了支持以上拦截程序,还支持一系列的拦截函数,我们选择几个常用的讲解!

ownKeys( )方法

ownKeys拦截操作,拦截过滤Object.ownKeys()对对象的属性遍历。

 //定义一个对象person,有三个属性
let person = {"name":"老王","age":40,"height":1.8}; //创建一个代理对象
let proxy = new Proxy(person,{
//ownKeys过滤对对象的属性遍历
ownKeys:function(target){
return ["name","age"]
}
}); Object.keys(person);
//结果:["name", "age","height"] Object.keys(proxy);
//结果:["name", "age"]

我们编写的ownKeys方法程序,不管你有多少属性,只返回两个属性name和age。我们看最后两行代码:Object.keys(person); 这里我们不使用代理,直接用keys( )函数遍历person对象,得到的person对象的原本属性"name"、 "age"和"height"。而Object.keys(proxy) 这句代码遍历的是被代理的proxy对象,所以,得到的只是被过滤后的结果:[“name”,”age”]。

has( )方法

has( )拦截操作:拦截key in object的操作,结果会返回一个布尔值。

    var person = {
"name":"张三",
"age":20
}; var proxy = new Proxy(person, {
has: function(target, prop) {
if(target[prop] === undefined){
return false;
}else{
return true;
}
}
}); "name" in proxy;//结果:true
"height" in proxy;//结果:false

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

对象含有name属性,所以返回true,没有height属性,返回false。

apply( )方法

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

    //创建一个函数fn
let fn = function(){
alert('我是前端君');
};
//创建一个代理实例,代理函数fn
let proxy = new Proxy(fn,{
apply:function(){
alert('我是隔壁老王');
}
}); proxy();//结果:我是隔壁老王

最后一句代码,proxy本身是一个代理实例对象,因为它代理的是一个函数fn,所以可以直接用函数的形式调用proxy( );当它当作函数调用的时候,就会被apply拦截,执行alert('我是隔壁老王')。

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的时候就会报错了,代理已经不存在了。

以上就是Proxy代理的介绍,关于其他的拦截操作就不一一介绍,包括:

  • defineProperty( )

  • deleteProperty( )

  • enumerate( )

  • getOwnPropertyDescriptor( )

  • getPrototypeOf( )

  • isExtensible( )

  • preventExtensions( )

  • setPrototypeOf( )

本节小结

总结:ES6带了的Proxy代理机制,它提供了一些拦截操作:set、get、apply、has、ownKeys等,我们可以根据特定的需求编写拦截程序,达到我们想要的效果;此外,我们也可以利用Proxy.revocable( )实现取消代理。
更多前端学习内容文章干货请关注我的专栏(不断更新)

阿里名厂标准web前端高级工程师教程目录大全,从基础到进阶,看完保证您的薪资上升一个台阶

在这里我给大家准备了很多的学习资料

其实你与阿里工程师的差距只差这些东西

新的知识点来了-ES6 Proxy代理 和 去银行存款有什么关系?的更多相关文章

  1. es6 proxy代理

    es6 新增构造函数 Proxy Proxy 构造函数,可以使用new 去创建,可以往里面插入两个参数,都是对象 let target = {} let handler = {} let proxy ...

  2. ES6 proxy代理详解及用法

    proxy官方的详细解释为代理器,个人理解为相当于一个拦截器,外部的所有访问必须先通过这层拦截,监视到对象的读写过程,因此提供了这 种机制对外部的访问进行过滤和修改. 上述例子为proxy new一个 ...

  3. ES6 proxy(代理拦截) &&Reflect

  4. ES6新特性:Proxy代理器

    ES6新特性:Proxy: 要使用的话, 直接在浏览器中执行即可, node和babel目前还没有Proxy的polyfill;,要使用的话,直接在浏览器中运行就好了, 浏览器的兼容性为:chrome ...

  5. 详解es6中Proxy代理对象的作用

    在es6中新添加了Proxy,那么它有什么作用啊?Proxy本意为代理,而es6中的Proxy也就是代理对象,那么代理对象感觉听起来很模糊,在这里就解释一下Proxy代理对象的作用. Proxy的主要 ...

  6. Vue3.0 响应式数据原理:ES6 Proxy

    Vue3.0 开始用 Proxy 代替 Object.defineProperty了,这篇文章结合实例教你如何使用Proxy 本篇文章同时收录[前端知识点]中,链接直达 阅读本文您将收获 JavaSc ...

  7. es6 Proxy对象详解

    Proxy用于修改某些操作的默认行为,也可以理解为在目标对象之前架设一层拦截,外部所有的访问都必须先通过这层拦截,因此提供了一种机制,可以对外部的访问进行过滤和修改.这个词的原理为代理,在这里可以表示 ...

  8. php设计模式之Proxy(代理模式)和Facade(外观)设计模式

    Proxy(代理模式)和Facade(外观)设计模式它们均为更复杂的功能提供抽象化的概念,但这两种实现抽象化的过程大不相同 Proxy案例中,所有的方法和成员变量都来自于目标对象,必要时,该代理能够对 ...

  9. Proxy 代理模式

    简介 代理模式是用一个简单的对象来代替一个复杂的或者创建耗时的对象. java.lang.reflect.Proxy RMI 代理模式是对象的结构模式.代理模式给某一个对象提供一个代理对象,并由代理对 ...

随机推荐

  1. python——新excel模块之openpyxl

    1.安装 pip install openpyxl 2.新建文件 book=openpyxl.Workbook() 3.打开sheet页(两种方式) sheet=book.active #默认的she ...

  2. Dome_iptest_server

    一个简单的ip测试服务器 打印返回 请求头request import socket def send_data(conn, data=None, status=200): if status != ...

  3. javascript中的符号 == 和 === 的区别

    ==  表示相等 即仅仅比较两边变量的数值是否相等. 相等运算符隐藏的类型转换,会带来一些违反直觉的结果. 这就是为什么建议尽量不要使用相等运算符. 至于使用相等运算符会不会对后续代码造成意外影响,答 ...

  4. SringBoot整合velocity及常用语法

    项目地址:https://github.com/chywx/springboot-velocity 背景 由于公司业务面向的是非洲市场 那边有些国家智能机并未普及,像乌干达地区还是以功能机为主 为了支 ...

  5. Java哈希表入门

    Java哈希表(Hash Table) 最近做题经常用到哈希表来进行快速查询,遂记录Java是如何实现哈希表的.这里只简单讲一下利用Map和HashMap实现哈希表. 首先,什么是Map和HashMa ...

  6. shell使用特殊变量

                                                                 shell使用特殊变量 3.1问题 本例要求编写一个脚本/root/myuse ...

  7. JVM 理解性学习(二)

    1.G1 垃圾回收器 G1 能更少的 "Stop the World" ,能同时对新生代老年代进行垃圾回收. G1 将 Java 堆内存拆分为多个大小相等的 Region,并且新生 ...

  8. java编写规范

    编码规范 转载于:https://www.cnblogs.com/ftl1012/p/javaCode.html 1 前言为确保系统源程序可读性,从而增强系统可维护性,java编程人员应具有基本类似的 ...

  9. 中阶d03.4 JDBC_DAO

    1.环境准备(单项目下用,在大jdbc项目下只用配置一次) jdbc的驱动(mysqlxxjdbc.jar).util工具(包装释放资源.建立连接.访问properties文件等方法) 2.dao的概 ...

  10. Java 方法 的使用

    简单的说: 方法就是完成特定功能的代码块– 在很多语言里面都有函数的定义– 函数在Java中被称为方法 • 格式:– 修饰符 返回值类型 方法名(参数类型 参数名1, 参数类型参数名2…) {函数体; ...