Created
May 23, 2017 01:46
-
-
Save xinlc/0f58536c7754bacdaa5e9bac818a116a to your computer and use it in GitHub Desktop.
js AOP 实现AOP,提供before和after通知
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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