面向对象设计里的设计模式之Proxy(代理)模式,相信不少朋友已经很熟悉了。好比我以前写过代理模式在Java中实现的两篇文章:javascript
Java代理设计模式(Proxy)的四种具体实现:静态代理和动态代理前端
Java动态代理之InvocationHandler最简单的入门教程java
其实和Java同样,JavaScript从语言层面来说,也提供了对代理这个设计模式的原生支持。咱们用一个不到100行代码的例子来看看吧。编程
下面的代码建立了一个名叫Jerry的Employee对象,而后用函数hireEmployee雇用该Employee进行JavaScript开发:设计模式
function Employee(name){ this.name = name; }; Employee.prototype.work = function(language){ console.log(this.name + " is developing with: " + language); } let jerry = new Employee("Jerry"); function hireEmployee(employee, language){ employee.work(language); } hireEmployee(jerry, "JavaScript");
打印输出:编程语言
Jerry is developing with: JavaScript函数
如今Jerry在他的业余时间里想学习一些其余的编程语言,可是不想影响本身的本职工做。用技术语言来说,就是但愿Employee原型方法work执行时,打印一行额外的信息,可是不容许修改Employee函数和Employee.prototype.work自己。这时Proxy这种代理模式就派上用场了。学习
咱们为work方法建立一个代理逻辑:this
var proxyLogic = { get: function(target, name) { if( name == "work"){ var oriFun = target[name].bind(target); return function(language){ oriFun(language); console.log("and also study other language in spare time"); } } } } ;
重点看第二行的get方法。两个输入参数,target和name。Target表明当前执行方法的实例,即方法调用者。Name表明具体的方法名称。第4行咱们把原始方法取出来,存放到变量oriFun里。第五行返回一个新的JavaScript函数,该函数体的实现逻辑为首先在第六行调用原始方法,而后在第七行执行额外的逻辑。spa
你们在回忆我以前介绍Java InvocationHandler实现动态代理的文章:
Java动态代理之InvocationHandler最简单的入门教程
是否是思路彻底同样?都是在代理逻辑里调用原始方法,而后再执行额外的代码。
这个proxyLogic生成后,怎么把它同咱们原始的须要被代理的代码关联起来呢?
只须要1行代码:
var jerryProxy = new Proxy(jerry, proxyLogic );
Proxy函数是JavaScript提供的原生代理构造器,须要两个输入参数:
第一个输入参数是咱们的Employee实例,即须要被代码的对象实例,第二个输入参数是咱们开发好的代理逻辑。返回的便是装配好的代理对象,该代理对象的work方法实如今第二个输入参数里。
如今咱们再次调用hireEmployee,传入Proxy构造器返回的代理对象:
hireEmployee(jerryProxy, "JavaScript");
打印输出,代理逻辑生效了:
和Java的Invocation同样优雅地实现了代理设计模式。
使用Proxy代理设计模式的一个实际例子,请参考个人文章:
巧用代理设计模式(Proxy Design Pattern)改善前端图片加载体验
要获取更多Jerry的原创技术文章,请关注公众号"汪子熙"或者扫描下面二维码: