日期:2014-05-16  浏览次数:20311 次

js实现的AOP雏形
  老早以前的东西了,发出来分享下。目前支持aop的框架实在很少,功能也挺残废的~ 运行还算稳定,不会对this指针造成干扰,经测试可对对象的方法、独立函数、构造函数等各种添加AOP支持,也可以解除AOP支持。使用advice链式结构实现,最大的特点应该是支持参数/返回值控制(即每个advice均有一个入口/出口,可以自由定制输入/输出策略)。不多说了,上代码,直接拿来用应该是木有问题的但是目前还只实现了before和after两个joinpoint,后续可能扩展一些,参数/返回值策略也有些小单调虽然扩展性不咋地但是基本需求应该能满足。后续如果有时间的话可能从这两点完善一下。

//外部接口

var AopUtil = {};

(function() {

    AopUtil.ALLOW_IN = 1;

    AopUtil.ALLOW_OUT = 2;

    var original = {};

    //缓存数据,新增before advice的时候会用到

    var beforeAdviceCounter = 0;

    //将原始方法变成代理方法的方法

    var createProxyMethod = function(originalItem) {

        return function() {

            var currentArg = arguments;

            var currentReturn = arguments;

            var lastReturn = arguments;

            //计算组合策略(参数+返回值策略)中的参数策略

            //isInAllowed为策略值二进制表示中的最低位值,isOutAllowed为次低位

            var isInAllowed, isOutAllowed;

            //当前函数的返回值

            var result;

            for (var i in originalItem.adviceChain) {

                //读取策略组

                isInAllowed = originalItem.adviceChain[i].strategy;

                isOutAllowed = isInAllowed >> 1;

                isInAllowed = isInAllowed - (isInAllowed >> 1 << 1);

                isOutAllowed = isOutAllowed - (isOutAllowed >> 1 << 1);

                if (isInAllowed) currentArg = lastReturn;

                else currentArg = arguments;

                currentReturn = [originalItem.adviceChain[i].method.apply(this, currentArg)];

                if (isOutAllowed) lastReturn = currentReturn;

            }

            return lastReturn[0];

        }

    }

    //对原始方法添加AOP支持

    var attachToAop = function(methodName, strategy) {

        if (original[methodName])  return null;

        var sourceMethod = eval(methodName);

        if (!sourceMethod) return null;

        //初始化adviceChain

        original[methodName] = {};

 &nb