代理模式(英语:Proxy Pattern)是程序设计中的一种设计模式。
所谓的代理者是指一个类别可以作为其它东西的接口。代理者可以作任何东西的接口:网络连接、内存中的大对象、文件或其它昂贵或无法复制的资源。
著名的代理模式例子为引用计数(英语:reference counting)指针对象。
当一个复杂对象的多份副本须存在时,代理模式可以结合享元模式以减少内存用量。典型作法是创建一个复杂对象及多个代理者,每个代理者会引用到原本的复杂对象。而作用在代理者的运算会转送到原本对象。一旦所有的代理者都不存在时,复杂对象会被移除。
上面是维基百科中对代理模式的一个整体的定义.而在JavaScript中代理模式的具体表现形式就是ES6中的新增对象---Proxy
在MDN上对于 Proxy 的解释是:
Proxy 对象用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)。
简单来说: Proxy 对象就是可以让你去对JavaScript中的一切合法对象的基本操作进行自定义.然后用你自定义的操作去覆盖其对象的基本操作.也就是当一个对象去执行一个基本操作时,其执行的过程和结果是你自定义的,而不是对象的.
:sweat:好吧,用文字表达可能太复杂了.我们还是直接上代码吧.
首先Proxy的语法是:
let p = new Proxy(target, handler);
其中:
然后让我们来看这段代码:
let obj = { a: 1, b: 2, } const p = new Proxy(obj, { get(target, key, value) { if (key === 'c') { return '我是自定义的一个结果'; } 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) // undefined console.log(p.a) // 1 console.log(p.c) // 我是自定义的一个结果 obj.name = '李白'; console.log(obj.name); // 李白 obj.age = 4; console.log(obj.age); // 4 p.name = '李白'; console.log(p.name); // 李白 p.age = 4; console.log(p.age); // 我是自定义的一个结果
从上面这段代码中,我可以很清楚的看到 Proxy 对象的作用.即是之前所受的 用于定义基本操作的自定义行为 .同样的 get 和 set 操作.没有没代理的对象所得的结果是其JavaScript本身的执行机制运行计算后所得到的.而被代理了的对象的结果则是我们自定义的.
在上面代码中,我们看到了构造一个代理对象时所传的第二个参数 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、 降低函数或类的复杂度
2、 在复杂操作前对操作进行校验或对所需资源进行管理
而对于这三个使用方面的具体表现大家可以参考这篇文章-- 实例解析ES6 Proxy使用场景
参考资料:
MDN---Proxy
实例解析ES6 Proxy使用场景
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
本文向大家介绍JavaScript设计模式之代理模式详解,包括了JavaScript设计模式之代理模式详解的使用技巧和注意事项,需要的朋友参考一下 代理模式是非常常见的模式,比如我们使用的VPN工具,明星的经纪人,都是代理模式的例子。但是,有人会疑问,明明可以直接访问对象,为什么中间还要加一个壳呢?这也就说到了代理模式的好处。在我看来,代理模式最大的好处,就是在不动原有对象的同时,可以给原有对象增
本文向大家介绍详解javascript设计模式三:代理模式,包括了详解javascript设计模式三:代理模式的使用技巧和注意事项,需要的朋友参考一下 代理模式是一种对程序对象进行控制性访问的一类解决方案。 引入代理模式,其实是为了实现单一职责的面向对象设计原则。 单一职责其实就是指在一个类中(js中通常指对象和函数等),应仅有一个引起它变化的原因。这样会帮助程序设计具有良好的健壮和高内聚特性,从
本文向大家介绍Java中的代理模式详解及实例代码,包括了Java中的代理模式详解及实例代码的使用技巧和注意事项,需要的朋友参考一下 java 代理模式详解 前言: 在某些情况下,一个客户不想或者不能直接引用一个对象,此时可以通过一个称之为“代理”的第三者来实现间接引用。代理对象可以在客户端和目标对象之间起到 中介的作用,并且可以通过代理对象去掉客户不能看到 的内容和服务或者添加客户需要的额外服务。
本文向大家介绍Java代理模式详细解析,包括了Java代理模式详细解析的使用技巧和注意事项,需要的朋友参考一下 代理模式是我们比较常用的设计模式之一。其中新思想是为了提供额外的处理或者不同的操作而在实际对象与调用者之间插入一个代理对象。这些额外的操作通常需要与实际对象进行通信,代理模式一般涉及到的角色有: 抽象角色:声明真实对象和代理对象的共同接口; 代理角色:代理对象角色内部含有对真实对象的引用
本文向大家介绍Python设计模式之代理模式实例详解,包括了Python设计模式之代理模式实例详解的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Python设计模式之代理模式。分享给大家供大家参考,具体如下: 代理模式(Proxy Pattern):为其他对象提供一种代理以控制对这个对象的访问 运行结果: jiaojiao 送你洋娃娃 jiaojiao 送你花 jiaojiao 送你巧克
本文向大家介绍详解ES6中class的实现原理,包括了详解ES6中class的实现原理的使用技巧和注意事项,需要的朋友参考一下 一、在ES6以前实现类和继承 实现类的代码如下: 实现继承的代码如下:一般使用原型链继承和call继承混合的形式 二、ES6使用class定义类 经过babel转码之后 可以看到ES6类的底层还是通过构造函数去创建的。 通过ES6创建的类,是不允许