前端AOP

前端工程化借鉴了很多后端的成功经验,设计模式,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 2

h1.remove();
obj.foo('hello world');
//before function 2
//obj and hello world
//after function 2

h2.remove();
obj.foo('hello world');
//obj and hello world

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

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

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值