使用AOP改善javascript代码

   这篇文章主要介绍了使用AOP改善javascript代码,需要的朋友可以参考下

  Aop又叫面向切面编程,用过spring的同学肯定对它非常熟悉,而在js中,AOP是一个被严重忽视的技术点,这篇就通过下面这几个小例子,来说说AOP在js中的妙用.

  1, 防止window.onload被二次覆盖.

  2,无侵入的统计代码.

  3, 分离表单请求和校验.

  4,给ajax请求动态添加参数.

  5,职责链模式.

  6, 组合代替继承.

  先给出before和after这2个“切面”函数. 顾名思义,就是让一个函数在另一个函数之前或者之后执行,巧妙的是,before或者after都可以和当前的函数公用this和arguments, 这样一来供我们发挥的地方就多着了.


  处理window.onload被二次覆盖.

  前段时间看到QQ群里有个人问问题,要改写window.onload, 怎么才能不把以前的window.onload函数覆盖掉.

  最原始的方案肯定是直接在原来的window.onload里添上你的新代码.


  这样的坏处非常明显,需要去改动原有的函数, 是侵入性最强的一种做法.

  另外一种稍微好点的方案是用中间变量保存以前的window.onload;


  这样一来,多了一个讨厌的中间变量__onload, 来管理它也要花费一些额外的成本.

  试想一下这个场景,当人觉得天气冷,出门的时候很自然选择穿上一件貂皮大衣,而不是把自己的皮扯掉换成貂皮. 动态装饰的好处就体现出来了,完全不会侵入之前的函数.


  无侵入的统计代码

  本身跟逻辑没有任何关联的统计代码要被硬插进函数里, 这点相信很多搞过上报的同学都很不爽. 比如下面这段代码, 用来统计一个创建1000个节点的函数在用户的电脑上要花费多少时间.


  用aop的方式,不再需要在函数内部做改动,先定义一个通用的包装器.


  只要一行代码,便能给任何函数都加上统计时间的功能.


  分离表单请求和校验

  我们在提交表单之前经常会做一些校验工作,来确定表单是不是应该正常提交. 最糟糕的写法是把验证的逻辑都放在send函数里面.


  而更好的方式是把所有的校验规则用策略模式放到一个集合里,返回false或者true来决定是否通过验证. 这样可以随意的选择和更换校验规则.


  这样还有一个缺点,校验和发送请求这2个请求耦合到了一个函数里面, 我们用aop来把它们分离开来, 把validata做成插件化,真正的即插即用. 只需把send函数改成:


  过最前面Function.prototype.before的代码不难看出,我们约定,当前一个函数返回false, 就会阻断下一个函数的执行, 所以当validata返回false的时候, 便不再继续执行send. 而因为之前提到的before函数可以和当前函数公用this和arguments, 所以value参数也能顺利的传递到validata函数里.

  给ajax请求动态添加参数

  第一个例子里window.onload是用的after后置装饰, 这里是用before前置装饰. 在ajax请求之前动态添加一些参数.

  我们遇到过很多跨域的请求, jsonp和iframe都是很常用的方式. 之前在我们的项目里,用参数retype=jsonp表示是jsonp请求, retype=iframe表示是iframe请求. 除此之外这2个请求的参数没有任何区别. 那么可以用before把retype参数动态装饰进去.

  先定义一个ajax请求的代理函数.


  这个函数里面没有逻辑处理和分支语句,它也不关心自己是jsonp请求还是iframe请求. 它只负责发送数据, 是一个单一职责的好函数.

  接下来在发送请求前放置一个before装饰器.


  开始发送请求:


  职责链模式.

  职责链模式在js中典型的应用场景是事件冒泡. 将所有子节点和父节点连成一条链,并沿着这条链传递事件,直到有一个节点能够处理它为止. 职责链模式是消除过多的if else语句的神器.

  拿最近做的一个需求来举例, 有个文件上传的功能, 提供了控件,html5, flash, 表单上传这4种上传方式. 根据它们的优先级以及浏览器支持情况来判断当前选择哪种上传方式. 在我进行改造之前,它的伪代码大概是这样:


  当然实际的代码远不只这么多,其中还包括了各种控件初始化,容错等情况。有天我需要屏蔽掉flash,看起来是很简单的需求,但难度实际跟在心脏旁边拆掉一根毛线血管类似.

  如果试试职责链模式呢, 看看事情将变得多简单:

  第一步先改写之前的after函数,使得返回一个对象时阻断职责链的传递,而返回null时继续传递请求。


  接下来把每种控件的创建方式都包裹在各自的函数中, 确保没有逻辑交叉和相互污染.


  最后用职责链把它们串起来:


  可以预见,某天我又需要屏蔽掉flash, 那时的我只需要改动这一行代码. 改成:


  组合代替继承

  很多时候我们在设计程序的时候,会遇到使用组合还是继承的问题. 通常来讲, 使用组合更灵活轻巧. 还是拿之前文件上传来举例.

  我定义了一个超类Upload, 衍生出4个子类.

  Plugin_Upload, Html5_Upload, Flash_Upload以及Form_Upload.

  Plugin_Upload会继承父类,得到Upload的大部分功能, 然后对控件上传的一些特性进行个性定制. 比如其它3种上传方式都是选择文件后便开始上传. 而控件上传在开始上传之前会经过一轮文件扫描.

  第一种做法是Plugin_Upload继承Upload, 然后重写它的start_upload方法.


  用更轻的组合方式, 可以直接给原来的start_upload函数装饰上扫描功能, 甚至不需要衍生一个额外的子类.

时间: 2024-09-30 01:16:17

使用AOP改善javascript代码的相关文章

用AOP改善javascript代码

  Aop又叫面向切面编程,用过spring的同学肯定对它非常熟悉,而在js中,AOP是一个被严重忽视的技术点,这篇就通过下面这几个小例子,来说说AOP在js中的妙用. 1, 防止window.onload被二次覆盖. 2,无侵入的统计代码. 3, 分离表单请求和校验. 4,给ajax请求动态添加参数. 5,职责链模式. 6, 组合代替继承. 先给出before和after这2个"切面"函数. 顾名思义,就是让一个函数在另一个函数之前或者之后执行,巧妙的是,before或者after都

5个书写JavaScript代码的坏习惯,看看你中枪了没?

 Javascript在互联网上名声很臭,但你又很难再找到一个像它这样如此动态.如此被广泛使用.如此根植于我们的生活中的另外一种语言.它的低学习门槛让很多人都称它为学前脚本语言,它另外一个让人嘲笑的东西是动态语言的概念是偏偏使用了高标准的静态数据类型.其实,你和Javascript都站错了立场,而现在,你让Javascript很生气.这里有五个原因能说明你的Javascript技术很烂. 1. 你没有使用命名空间. 是否还记得在大学里老师告诉你不要在家庭作业里使用全局变量?Javascript里

深入理解JavaScript系列(1) 编写高质量JavaScript代码的基本要点_javascript技巧

具体一点就是编写高质量JavaScript的一些要素,例如避免全局变量,使用单变量声明,在循环中预缓存length(长度),遵循代码阅读,以及更多. 此摘要也包括一些与代码不太相关的习惯,但对整体代码的创建息息相关,包括撰写API文档.执行同行评审以及运行JSLint.这些习惯和最佳做法可以帮助你写出更好的,更易于理解和维护的代码,这些代码在几个月或是几年之后再回过头看看也是会觉得很自豪的. 书写可维护的代码(Writing Maintainable Code ) 软件bug的修复是昂贵的,并且

《JavaScript专家编程》——9.4 度量JavaScript代码质量

9.4 度量JavaScript代码质量 为了让计算精度上升到最高,客观质量分析以程序化的方式对代码进行分析.这项任务可以使用编程工具完成,这些工具能够在多种情况下评估代码,根据各项指标得到最终的质量得分.本节介绍了静态代码分析,这种方法非常适合评估JavaScript的质量. 静态代码分析 静态代码分析就是不通过运行代码来分析代码的过程.静态分析看起来非常像一个文本编辑器的拼写检查器.拼写检查器扫描文档的正文来寻找错误和含糊之处,而并不需要了解文本的意义.同时,静态代码分析从功能上分析源代码的

5个书写JavaScript代码的坏习惯,看看你中枪了没?_javascript技巧

Javascript在互联网上名声很臭,但你又很难再找到一个像它这样如此动态.如此被广泛使用.如此根植于我们的生活中的另外一种语言.它的低学习门槛让很多人都称它为学前脚本语言,它另外一个让人嘲笑的东西是动态语言的概念是偏偏使用了高标准的静态数据类型.其实,你和Javascript都站错了立场,而现在,你让Javascript很生气.这里有五个原因能说明你的Javascript技术很烂. 1. 你没有使用命名空间. 是否还记得在大学里老师告诉你不要在家庭作业里使用全局变量?Javascript里的

编写高质量JavaScript代码的基本要点_javascript技巧

才华横溢的Stoyan Stefanov,在他写的由O'Reilly初版的新书<JavaScript Patterns>(JavaScript模式)中,我想要是为我们的读者贡献其摘要,那会是件很美妙的事情.具体一点就是编写高质量JavaScript的一些要素,例如避免全局变量,使用单变量声明,在循环中预缓存length(长度),遵循代码阅读,以及更多. 此摘要也包括一些与代码不太相关的习惯,但对整体代码的创建息息相关,包括撰写API文档.执行同行评审以及运行JSLint.这些习惯和最佳做法可以

推荐10 个短小却超实用的 JavaScript 代码段(http://www.jianshu.com/p/3ef822ec5a63)

文章转自<http://www.jianshu.com/p/3ef822ec5a63>,感谢作者分享! 推荐10 个短小却超实用的 JavaScript 代码段 字数2018 阅读4777 评论8 喜欢203 JavaScript正变得越来越流行,它已经成为前端开发的第一选择,并且利用基于JavaScript语言的NodeJS,我们也可以开发出高性能的后端服务,甚至我还看到在硬件编程领域也出现了JavaScript的身影.JavaScript正在逐渐进化为一门全能的开发语言. 但用好JavaS

for层次-用javascript代码写出来,怎么写

问题描述 用javascript代码写出来,怎么写 解决方案 html中的javascript代码怎么写javascript 写的tab页代码写javascript代码的技巧 解决方案二: alert(* ** ** * ); 解决方案三: alert(* ** ** * ); 解决方案四: alert确实可以,但是太土了,而且是个弹窗啊 这个题是考你for循环的使用,每次打出几个*** 算是一个算法吧,这个你可以搜一下,三角形代码输出算法,然后改一下输出行数和*的个数就可以了!! 解决方案五:

JavaScript代码教程:惰性载入函数

文章简介:因为浏览器之间行为的差异,多数JavaScript代码包含了大量的if语句,将执行引导到正确的代码中.看看XMLHttpRequest(XHR)对象中的createXHR()函数. 因为浏览器之间行为的差异,多数JavaScript代码包含了大量的if语句,将执行引导到正确的代码中.看看XMLHttpRequest(XHR)对象中的createXHR()函数: function createXHR() { if (typeof XMLHttpRequest != "undefined&