引:AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。

这里我们可以理解为在执行某函数时,要先执行什么,或最后执行什么。

比如:

  1. function a() {
  2. alert(1)
  3. }
  4. function b() {
  5. alert(2)
  6. }
  7.  
  8. //如果要先打印1再打印2
  9. a();
  10. b();
  11. //又或者把a()改为
  12. function a(){
  13. alert(1);
  14. b();
  15. }

第一种方法显得累赘,而且在改造升级的情况下,可能会使function b()没了,然后会报错,第二种方法代码入侵性太大。

我们可以使用AOP去改善这种逻辑。
关于实现和应用场景大家可以参考alloyteam,这文章(http://www.alloyteam.com/2013/08/yong-aop-gai-shan-javascript-dai-ma/

现在这里讨论的是after函数如何使用原函数的局部变量。
就拿alloyteam代码做个例子。

AOP实现:

  1. Function.prototype.before = function (func) {
  2. var __self = this;
  3. return function () {
  4. if (func.apply(this, arguments) === false) {
  5. return false;
  6. }
  7. return __self.apply(this, arguments);
  8. }
  9. }
  10.  
  11. Function.prototype.after = function (func) {
  12. var __self = this;
  13. return function(){
  14. var ret = __self.apply(this, arguments);
  15. if (ret === false) {
  16. return false;
  17. }
  18. func.apply(this, arguments);
  19. return ret;
  20. }
  21.  
  22. }

那么刚才的例子可以写成这样:

  1. var a = a.after(b);
  2. a();

现在想要函数b可以用到函数a里面的一个变量,就要使函数a最后return 返回变量。
如果我们不想改变函数a,又或者函数a的第三方代码,那怎么办,改动起来无疑麻烦,这里我新建一个方法insertAfter,
虽然这个改造有入侵性,但我们可以选择性使用这个方法。

  1. Function.prototype.insertAfter = function (func) {
  2. var oldFuncStr = this.toString();
  3. var aftFuncStr = func.toString();
  4. oldFuncStr = oldFuncStr.replace(/^function(.*){/, '');
  5. var newFuncStr = oldFuncStr.replace(/}$/, '~'+aftFuncStr+'()');
  6. var newFunc = new Function ("", newFuncStr);
  7. return newFunc;
  8. }

这样,after进去的函数就可以使用原函数的局部变量了。
注意原函数有return的情况,就应该把after内容放在return前面,如果是return false,可以忽略了。这里只给出思路。希望读者可以自行改造。
下面给出完整例子:

  1. Function.prototype.insertAfter = function (func) {
  2. var oldFuncStr = this.toString();
  3. var aftFuncStr = func.toString();
  4. oldFuncStr = oldFuncStr.replace(/^function(.*){/, '');
  5. var newFuncStr = oldFuncStr.replace(/}$/, '~'+aftFuncStr+'()');
  6. var newFunc = new Function ("", newFuncStr);
  7. return newFunc;
  8. }
  9.  
  10. //Usage
  11. function a(){
  12. var x = 123;
  13. alert(1);
  14. }
  15.  
  16. function b(){
  17. alert(x);
  18. }
  19.  
  20. var a = a.insertAfter(b);
  21. a();

给AOP的after函数使用原函数局部变量的更多相关文章

  1. 第十二篇 Python函数之全局变量&局部变量&递归函数

    全局变量:在定义的时候,顶头写的,没有任何缩进的变量就是全局变量. 全局变量的特点:在当前文件里的任何地方都可以进行调用 局部变量:在子程序里定义的变量,就是局部变量. 子程序:比如.py文件里,写的 ...

  2. Python新手学习基础之函数-全局变量和局部变量

    全局变量和局部变量 我们通常把定义在函数外的变量成为全局变量,定义在函数内的变量称为局部变量,顾名思义,全局变量的作用域是整个代码段,局部变量的作用域就只是在它所属的代码段,变量只在它的作用域里有效. ...

  3. JS模式--装饰者模式(用AOP动态改变函数的参数)

    Function.prototype.before = function (beforefn) { var _self = this; return function () { beforefn.ap ...

  4. Python自动化--语言基础3--字典、函数、全局/局部变量

    字典 dict1 = {'name':'han','age':18,'class':'first'} print(dict1.keys()) #打印所有的key值 print(dict1.values ...

  5. c c++ 函数不要返回局部变量的指针

    结论:普通的变量(非new的变量)都是系统自动分配的,在栈空间(连续分配),无需程序员操作,速度快,但是...空间有限,不适合大量数据,大量的话就需要自己new new出来的变量是处于大容量的堆空间, ...

  6. 【逆向工具】IDA使用2-VS2015版本release查找main函数入口,局部变量

    VS2015版本release查找main函数入口 vc++开发的程序main或WinMain函数是语法规定的用户入口,而不是应用程序入口.入口代码是mainCRTstartup.wmainCRTSt ...

  7. Python3基础 global 使函数中的局部变量升格为全局变量

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  8. C指针函数中的局部变量返回

    所谓指针函数其实就是  :一个函数的返回值为指针. 指针函数定义:返回类型标识符*  函数名(形参列表){函数体} eg:   int*  fun1(int n){} 指针函数和局部变量返回解析: 简 ...

  9. Python3基础(3)集合、文件操作、字符转编码、函数、全局/局部变量、递归、函数式编程、高阶函数

    ---------------个人学习笔记--------------- ----------------本文作者吴疆-------------- ------点击此处链接至博客园原文------ 1 ...

随机推荐

  1. 转:Connection: close和Connection: keep-alive有什么区别?

    原文:http://www.cnblogs.com/TinyMing/p/4597136.html 一.问题现象: 一个JSP页面,居然要耗时40多秒.网页中有大量的图片的CSS问题解决: 原因也找了 ...

  2. Linux:去除认证,加速 SSH登录

    编辑配置文件 /etc/ssh/sshd_config vim /etc/ssh/sshd_config 找到 UseDNS选项,如果没有注释,将其注释 #UseDNS yes 添加 UseDNS n ...

  3. Orcle常用语句

    在SQLPlus界面的操作语句: 查看\设置每行内显示的字符数:show\set linesize [linesize] 查看\设置一次显示的行数:show\set pagesize [pagesiz ...

  4. 第五百八十天 how can I 坚持

    一定要稳住啊,怎么感觉心神不宁呢.哎.越是这种情况越能考验一个人吧. 说都会说,做起来真的好难啊. 今天上班一天都感觉心神不宁的.到底是哪出了问题,事情太多了.好吧,是挺多的,考研.上班,还得考虑结婚 ...

  5. Windows的拖放操作使用方法

    Windows的拖放操作使用方法

  6. 自定义控件EditText

    public class defineEditText extends EditText { Context context; Drawable d; public defineEditText(Co ...

  7. android 多线程 示例

    public class MyRun implements Runnable { int count = 1000; @Override public void run() { while (true ...

  8. 创建maven项目时,提示 overlaps the workspace location

    创建maven项目时提示: Invalid project description.OKF:\java\mywork overlaps the workspace location: F:\java\ ...

  9. SQL 中 SELECT 语句的执行顺序

    好像自已在书写 SQL 语句时由于不清楚各个关键字的执行顺序, 往往组织的 SQL 语句缺少很好的逻辑, 凭感觉 "拼凑" ( 不好意思, 如果您的 SQL 语句也经常 " ...

  10. for 循环

    #include <iostream> int main(){ ; ; val <= ; ++val) { sum += val; } std::cout << &quo ...