Skip to content

Instantly share code, notes, and snippets.

@xinlc
Created May 23, 2017 01:46
Show Gist options
  • Save xinlc/0f58536c7754bacdaa5e9bac818a116a to your computer and use it in GitHub Desktop.
Save xinlc/0f58536c7754bacdaa5e9bac818a116a to your computer and use it in GitHub Desktop.
js AOP 实现AOP,提供before和after通知
/**
* js AOP
* 实现AOP,提供before和after通知
* @author Leo
*/
!function(global, undefined){
var aspect = function(){};
//aop核心实现
aspect.core = function (params,advice){
var source = params.source;
var method = params.method;
var exist = source[method];
//上一个fn或原始fn
var prev = function(){
return exist.apply(source, arguments);
};
//当前fn并继承上一个fn
var curr = advice(params,prev);
//替换原fn
source[method] = function(){
return curr ? curr.apply(source, arguments) : prev.apply(source, arguments);
};
//添加移除通知功能
return {
remove: function(){
curr = null;
advice = null;
}
};
};
//前置通知实现
aspect.beforeAdvice = function (params,original){
return function() {
var advice = params.advice;
var isBreak = !!params.isBreak;
var value = advice(params,arguments);
//是否跳出
if(isBreak){
if(value === false){
return;
}
original.apply(this, arguments);
}else{
original.apply(this, arguments);
}
};
};
//后置通知实现
aspect.afterAdvice = function (params,original){
return function() {
var value = original.apply(this, arguments);
var advice = params.advice;
advice(value);
};
};
/**
* 前置通知
* @param {source,method,advice,isBreak}
* @returns function remove
*/
aspect.prototype.before = function(params){
return aspect.core(params,aspect.beforeAdvice);
};
/**
* 后置通知
* @param {source,method,advice}
* @returns function remove
*/
aspect.prototype.after = function(params){
return aspect.core(params,aspect.afterAdvice);
};
var aspectFn = new aspect();
//支持amd
if ( typeof define === "function" && define.amd ) {
define(function() {
return aspectFn;
});
}else{
//如果不支持amd 使用对外提供的接口
global.Aspect = aspectFn;
}
}(window);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment