aop.js 1.67 KB
define(function () {
    return {
        /**
         * 切入点
         * @param {RegExp} pointcut - 符合规则的函数名称
         * @param {Function} advice - 切入的函数
         * @param {Array} namespace - 可选, 默认为window对象 
         */
        around: function (pointcut, advice, namespace) {
            var ns = namespace || (0, eval)('this');

            Object.keys(ns).forEach(function (member) {
                if (typeof ns[member] === "function" && member.match(pointcut)) {
                    ns[member] = (function (fn, fnName, ns) {
                        return function () {
                            return advice.call(ns, {
                                fn: fn,
                                fnName: fnName,
                                arguments: arguments
                            });
                        };
                    })(ns[member], member, ns);
                }
            });
        },
        next: function (f) {
            return f.fn.apply(this, f.arguments);
        },
        before: function (pointcut, advice, namespace) {
            var aop = this;

            aop.around(pointcut,
                function (f) {
                    advice.apply(this, f.arguments);
                    return aop.next(f);
                },
                namespace);
        },
        after: function (pointcut, advice, namespace) {
            var aop = this;

            aop.around(pointcut,
                function (f) {
                    var ret = aop.next(f);
                    advice.apply(this, f.arguments);
                    return ret;
                },
                namespace);
        }
    };
});