zoukankan      html  css  js  c++  java
  • 100行代码让您学会JavaScript原生的Proxy设计模式


    面向对象设计里的设计模式之Proxy(代理)模式,相信很多朋友已经很熟悉了。比如我之前写过代理模式在Java中实现的两篇文章:

    Java代理设计模式(Proxy)的四种具体实现:静态代理和动态代理

    Java动态代理之InvocationHandler最简单的入门教程

    其实和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方法创建一个代理逻辑:

    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函数,该函数体的实现逻辑为首先在第六行调用原始方法,然后在第七行执行额外的逻辑。

    大家在回忆我之前介绍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的原创技术文章,请关注公众号"汪子熙"或者扫描下面二维码:

  • 相关阅读:
    .Net 第三方控件(转)
    DevExpress控件之GridControl控件
    sql语句linq语言lambda表达式对照
    匿名方法和Lambda表达式
    LINQ To ADO.Net中几个方法(1)
    const与readonly的区别
    InvokeRequired 属性 与Invoke方法
    DevExpress控件使用
    VC菜单操作
    VC获取各类指针
  • 原文地址:https://www.cnblogs.com/sap-jerry/p/9818856.html
Copyright © 2011-2022 走看看