所谓的代理者是指一个类别可以作为其它东西的接口. 代理者可以作任何东西的接口: 网络连接, 内存中的大对象, 文件或其它昂贵或无法复制的资源. 著名的代理模式例子为引用计数 (英语: reference counting) 指针对象.
当一个复杂对象的多份副本须存在时, 代理模式可以结合享元模式以减少内存用量. 典型作法是创建一个复杂对象及多个代理者, 每个代理者会引用到原本的复杂对象. 而作用在代理者的运算会转送到原本对象. 一旦所有的代理者都不存在时, 复杂对象会被移除.
- var backPhoneList = ['12345566'];// 黑色单列表
- // 代理
- var ProxyAcceptPhone = function(phone){
- console.log('电话正在接入...')
- if(backPhoneList.includes(phone)){
- console.log('屏蔽黑名单电话')
- }else{
- // 转接
- AcceptPhone.call(this,phone)
- }
- }
- // 本体
- var AcceptPhone = function(phone){
- console.log('接听电话',phone)
- }
- // 外部调用代理
- ProxyAcceptPhone('12345566')
- ProxyAcceptPhone('18900044440')
什么是 Proxy 对象?
Proxy 对象就是可以让你去对 JavaScript 中的一切合法对象的基本操作进行自定义. 然后用你自定义的操作去覆盖其对象的基本操作. 也就是当一个对象去执行一个基本操作时, 其执行的过程和结果是你自定义的, 而不是对象的.
首先 Proxy 的语法是:
let p = new Proxy(target, handler);
1. target 是你要代理的对象. 它可以是 JavaScript 中的任何合法对象. 如: (数组, 对象, 函数等等)
2. handler 是你要自定义操作方法的一个集合.
3. p 是一个被代理后的新对象, 它拥有 target 的一切属性和方法. 只不过其行为和结果是在 handler 中自定义的.
在支持 Proxy 的浏览器环境中, Proxy 是一个全局对象, 可以直接使用. Proxy(target, handler) 是一个构造函数, target 是被代理的对象, handlder 是声明了各类代理操作的对象, 最终返回一个代理对象. 外界每次通过代理对象访问 target 对象的属性时, 就会经过 handler 对象, 从这个流程来看, 代理对象很类似 middleware(中间件). 那么 Proxy 可以拦截什么操作呢? 最常见的就是 get(读取),set(修改)对象属性等操作, 此外, Proxy 对象还提供了一个 revoke 方法, 可以随时注销所有的代理操作.
- let obj ={
- a:1,
- b:2
- }
- const p = new Proxy(obj,{
- get(target,key,value){
- if(key == 'c'){
- return '我是自定义的 2 一个结果'
- }else{
- return target[key];
- }
- },
- set(target,key,value){
- if(value==4){
- target[key]='我是自定义的一个结果'
- }else{
- target[key] = value;
- }
- }
- })
- console.log(obj.a)//1
- console.log(obj.c)//underfined
- console.log(p.a)//1
- console.log(p.c)// 我是自定义的一个结果
- obj.name = '李白'
- console.log(obj.name)// 李白
- console.log(p.name)// 李白
- p.age=4
- console.log(obj.age)// 我是自定义的一个结果
- console.log(p.age)// 我是自定义的一个结果
Proxy 对象的作用. 即是之前所受的用于定义基本操作的自定义行为. 同样的 get 和 set 操作. 没有没代理的对象所得的结果是其 JavaScript 本身的执行机制运行计算后所得到的. 而被代理了的对象的结果则是我们自定义的.
Proxy 所能代理的范围 --handler
在上面代码中, 我们看到了构造一个代理对象时所传的第二个参数 handler, 这个 handler 对象是由 get 和 set 两个函数方法组成的. 这两个方法会在一个对象被 get 和 set 时被调用执行, 以代替原生对象上的操作. 那么为什么在 handler, 定义 get 和 set 这两个函数名之后就代理对象上的 get 和 set 操作了呢? 实际上 handler 本身就是 ES6 所新设计的一个对象. 它的作用就是用来自定义代理对象的各种可代理操作. 它本身一共有 13 中方法, 每种方法都可以代理一种操作.
其 13 种方法如下:
- handler.getPrototypeOf()
- // 在读取代理对象的原型时触发该操作, 比如在执行 Object.getPrototypeOf(proxy) 时.
- handler.setPrototypeOf()
- // 在设置代理对象的原型时触发该操作, 比如在执行 Object.setPrototypeOf(proxy, null) 时.
- handler.isExtensible()
- // 在判断一个代理对象是否是可扩展时触发该操作, 比如在执行 Object.isExtensible(proxy) 时.
- handler.preventExtensions()
- // 在让一个代理对象不可扩展时触发该操作, 比如在执行 Object.preventExtensions(proxy) 时.
- handler.getOwnPropertyDescriptor()
- // 在获取代理对象某个属性的属性描述时触发该操作,
- // 比如在执行 Object.getOwnPropertyDescriptor(proxy, "foo") 时.
- handler.defineProperty()
- // 在定义代理对象某个属性时的属性描述时触发该操作,
- // 比如在执行 Object.defineProperty(proxy, "foo", {
- }) 时.
- handler.has()
- // 在判断代理对象是否拥有某个属性时触发该操作, 比如在执行 "foo" in proxy 时.
- handler.get()
- // 在读取代理对象的某个属性时触发该操作, 比如在执行 proxy.foo 时.
- handler.set()
- // 在给代理对象的某个属性赋值时触发该操作, 比如在执行 proxy.foo = 1 时.
- handler.deleteProperty()
- // 在删除代理对象的某个属性时触发该操作, 比如在执行 delete proxy.foo 时.
- handler.ownKeys()
- // 在获取代理对象的所有属性键时触发该操作, 比如在执行 Object.getOwnPropertyNames(proxy) 时.
- handler.apply()
- // 在调用一个目标对象为函数的代理对象时触发该操作, 比如在执行 proxy() 时.
- handler.construct()
- // 在给一个目标对象为构造函数的代理对象构造实例时触发该操作, 比如在执行 new proxy() 时.
Proxy 的作用
对于代理模式 Proxy 的作用主要体现在三个方面:
1, 拦截和监视外部对对象的访问
2, 降低函数或类的复杂度
3, 在复杂操作前对操作进行校验或对所需资源进行管理
自己是一个 6 年的前端工程师, 希望本文对你有帮助!
这里推荐一下我的前端学习交流扣 qun:731771211 , 里面都是学习前端的, 如果你想制作酷炫的网页, 想学习编程. 自己整理了一份 2019 最全面前端学习资料, 从最基础的 html+CSS+JS[炫酷特效, 游戏, 插件封装, 设计模式] 到移动端 HTML5 的项目实战的学习资料都有整理, 送给每一位前端小伙伴, 每天分享技术
点击: 加入
来源: http://www.jianshu.com/p/7c1386208e62