前端AOP

来源:互联网 发布:软件需求分析文档 编辑:程序博客网 时间:2024/05/15 04:10

前端工程化借鉴了很多后端的成功经验,设计模式,MVC,组件化与模块化等,再结合前端本身的分层与分治的特点,逐渐变得复杂。

在angular里ioc,di的概念也开始盛行,而且结合的还不错,不过aop这种说法还真少见,可能是我太孤陋寡闻了吧,不免去百度一下。

一开始听到前端AOP这个提法我还有些吃惊,我是会后端开发的,SPRING的AOP已深入人心,面向切片与切入点都是核心概念,但是javascript做AOP还是真没在项目里做过。js是解释型的语言,语法松散灵活,是一种非强类型的语言,它是一种天生的函数式语言,除了值类型,一些皆为对象,包括函数,前端开发一直以来都是一个页面一个页面地生产的,做AOP的意义何在?而且也没有听说哪个框架里有AOP。后来一查,还真有,在DOJO这个框架里比较流行,不过DOJO我一直没用过,所以就没深入去了解。

所以,我说AOP如果需要用的话,可以用JS闭包来做,在调用其他方法前先调用一个切面方法。现在想想,我觉得这样说也没错,前端模块化基本都是用闭包来实现的,如果不做封装,都是松散的JS文件,何谈AOP?

AOP一般用在哪儿呢?日志记录、权限检查、事务处理,我想权限检查和事务处理最好是放到后端去做,一是为了安全,二是好控制,事务很难在界面逻辑上控制,但在后端的业务逻辑或数据库层就容易的多,而权限检查在前端做就不安全,因为JS和HTML都是文本格式的,代码在前端是暴露的,只能做一些弱检查。日志记录可能是前端AOP主要的一个应用方向吧,但前端代码是在浏览器里运行的,日志记录也很难记到文件里,只能利用cookie或console,前者不适应记录日志,因为会降低性能,而后者主要用来做调试代码用,这么看来,我觉得AOP的作用并不明显,了解一下即可。

使用回调的方式实现AOP:

advice = function(originalFunc){    console.log("before function");    originalFunc();    console.log("after function");}varobj ={    foo: function(){        console.log('foo');    }}advice(obj.foo)

这最简单不过了,要想使用AOP,我们不得不通过advice来调用每一个方法,这种方式的确不够友好。
需要做一些封装,使用闭包来控制:(以下代码来源于网络)

function around(obj, prop, advice){    var exist =obj[prop];    var previous = function(){        return exist.apply(obj, arguments);    };    var advised =advice(previous);    obj[prop] = function(){        //当调用remove后,advised为空        //利用闭包的作用域链中可以访问到advised跟previous变量,根据advised是否为空可以来决定调用谁        return advised ?advised.apply(obj, arguments) : previous.apply(obj, arguments);    };    return{        remove: function(){            //利用闭包的作用域链,在remove时将advised置空,这样执行过程中不会进入本次around            //这几个不能删            //obj[prop] = exist;            advised = null;            advice = null;            //previous = null;            //exist = null;            //obj = null;        }    }}var count = 1;advice = function(originalFunc){    var current = count++;    return function() {        console.log("before function " +current);        originalFunc.apply(this, arguments);        console.log("after function " +current);    }}var obj ={    foo: function(arg){        console.log(this.name + " and " +arg);    },    name: "obj"}h1 = around(obj, 'foo', advice);h2 = around(obj, 'foo', advice);obj.foo('hello world');//before function 2//before function 1//obj and hello world//after function 1//after function 2h1.remove();obj.foo('hello world');//before function 2//obj and hello world//after function 2h2.remove();obj.foo('hello world');//obj and hello world

around前面两个参数指定了对象和对象上的方法,后一个参数指定了切面方法,调用apply的目的是防止this指向脱离obj。

为了记录个日志调试一下,这么大费周章,而且代码即不易于理解也显多余,看来前端AOP的用处真的不太大呀。

0 0
原创粉丝点击