好好爱自己!

AOP 在javascript 中的使用

AOP(Aspect Oriented Programming) 意为面向切面编程

可以在不修改原有代码的情况下增加新功能,利用AOP可以对业务逻辑各个部分进行隔离,从而使得业务逻辑各部分的耦合度降低,提高程序的可重用性。

主要功能

日志记录,性能统计,安全控制,事务处理,异常处理等等

主要意图

将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。

 

javascript 中的 onload 事件,

支持该事件的HTML标签: <body>, <frame>, <frameset>, <iframe>, <img>, <link>, <script>

支持该事件的javascript 对象: image , layer, window

(

  Array.prototype.slice(begin, end) 这个方法是 返回数组的一部分, begin不写为0, end不写为数组的末尾;

  push(2) 数组的末尾插入 数字2,

  pop() 从数组的末尾删除一个元素,

  shift() 从数组的开头删除一个元素,

   unshift() 从数组的开头插入一个元素。

用的比较多的,通过document.getElementsByTagName选择的dom 节点是一种类似array的array。它不能应用Array下的push,pop等方法。我们可以通过:
var domNodes = Array.prototype.slice.call(document.getElementsByTagName("*")); 这个里面 begin ,end两个参数都每传。
这样domNodes就可以应用Array下的所有方法了

)

 AOP 大量运用于:权限控制、日志记录、数据校验、异常处理、主动通知等领域。     

AOP 主要思想是把一些与核心业务无关但又在多个模块使用的功能分离出来,然后动态给业务模块添加上 需要的功能。。JavaScript 有得天独厚的动态解析执行的优势,用来实现类似 AOP 这样的模式是非常简单的,

 

在AOP 编程领域, before , after 这两个是“切面”函数, 就是让一个函数在另一个函数之前或者之后执行,巧妙的是, before 和 after 都可以和当前的函数共用 this  和 arguments, 

 

为什么要 AOP, 举一个简单的例子:

 

清单 1. 一个简单的 HTML 表单
 <form action="/test.jsp" method="post"> 
        <input type=”text” name=”username” /> 
        <input type="submit" /> 
 </form>
这是一个最简单的 form 表单,看起来没什么问题。但在低速网络环境下,心急的浏览者没耐心等待,很可能会重复提交表单,如图 1。

作为一个 Web 开发者,我们是绝对不希望浏览者重复提交表单的,这时您可能会想到以下方案
清单 2. 表单提交时禁用 submit 按钮
 <form action="/test.jsp" method="post"> 
        <input type=”text” name=”username” /> 
        <input type="submit" onClick="this.disabled=true;" /> 
 </form>
很好,问题解决了,点击“提交”按钮同时该按钮也被禁用了,这样浏览者就不能重复提交了。
可是,如果您的工程很大,有成百上千个页面,每个页面都有一段类似的代码,难道您还独自编辑吗?如果有一天要在按钮 disabled 之前 alert 一个提示信息,那您还不抓狂?

 

  

基于 AOP 思想的解决方案

前面我讲过“AOP 主要思想是把一些与业务无关但又在多个模块使用的功能分离出来”,在这里,每个页面都可以看作是一个模块,而“表单提交时禁用提交按钮”这个功能就可以分离出来,在不改变各模块代码的前提下为模块织入此功能。(注:实际上还是要修改代码的,因为要引入 .js 文件,但这非常简单,完全可以使用工具批量完成,并且是一劳永逸的)。下面谈谈具体的实现思路:

  • 把禁用 submit 按钮的代碼封裝成 function,写入 JS 文件(在 AOP 领域,这个 function 的术语叫做 “通知(Advice)” );
  • 在各页面引入该 JS 文件;
  • JS 引入时,把原 submit 事件处理函数备份起来;
  • 把 submit 事件处理函数替换成我们的通知 function;
  • 其中,通知 function 要做两件事情:
  1. 禁用 submit 按钮;
  2. 调用备份好的原 submit 事件处理函数;
 // 这就是我们要实现的通知 function 
 function disableFormSubmitButton(){ 

        // 首先获取要操作的 DOM 对象 ( 织入点 ),我们需要拦截所有 form,代码如下 $("form") 
        // 因为一个页面可能会有多个 <form>,所以这里需要遍历
        $("form").each(function(i, v){ 
                // 原 submit 事件函數,备份成 _ invokesubmit,
                //_invokesubmit 是随便起的名字,充分利用了 javascript 的动态特性。 
                v._invokesubmit = v.onsubmit ; 
                // 替换原 submit 事件函數
                v.onsubmit = function(){ 
                    // 禁用提交表单按钮 
                $(this).find(“input[type= 'submit']”).prop(“disabled”, true);
                v._invokeprocess();// 调用备份的 submit 事件函数 
                }; 
        }); 
 }

  图 2:应用 AOP 前后的示意图

 

 

下面是我自己实现 -:)的一段 AOP 的代码:

 

 

  Cat.prototype = {
        food: "fish",
        say: function(){
            alert("i like " + this.food);
            return this;
        },
        after: function(func){
            func.call(this);
        },
        before: function(func){
            func.call(this);
            return this;
        }

    };

    var cat = new Cat()
    Dog = {food: "bone"};
    cat.before(function(){
        alert("before" + this.food);
    }).say().after(function(){
        alert("after" + this.food);
    })

 

  

 

posted @ 2016-04-25 17:33  立志做一个好的程序员  阅读(304)  评论(0编辑  收藏  举报

不断学习创作,与自己快乐相处