AOP的概念,使用過Spring的人應該都不陌生了。Dojo中,也是支持AOP的。對於JavaScript的其他框架、庫不知道有沒有AOP的支持。而Aop又叫面向切面編程,用過spring的同學肯定對它非常熟悉,而在js中,AOP是一個被嚴重忽視的技術點,這次就來說說AOP在js中的妙用
AOP的思維就是在目標方法前後加入代碼:
var result=null;
try{
before();
result = targetMethod(params);
}(catch e){
error();
}finlly{
after();
}
return result;
在JavaScript中要達到AOP的效果可以利用apply(ctx,arguments)來達到目的,請看下面demo:
這是一個原始的代碼:
function Person(options){
options = options ? options : {};
this.id = options.id;
this.age = options.age>0 ? options.age:0;
}
Person.prototype.show=function(){
console.log("id: "+this.id + " age: "+ this.age);
};
var p = new Person({
id:'test1',
age:1
});
p.show();
現在想要對show方法植入代碼,利用apply這樣寫就Ojbk了:
var targetFunc = Person.prototype.show;
var proxyFunc = function(){
var ctx = this;
console.log("before ...");
targetFunc.apply(ctx, arguments);
console.log("after ...");
}
Person.prototype.show = proxyFunc;
p = new Person({
id:"test2",
age:2//歡迎加入全棧開發交流圈一起學習交流:864305860
});//面向1-3年前端人員
p.show();//幫助突破技術瓶頸,提升思維能力
如果要對各種方法植入,這樣寫肯定是不方便了,所以呢,將這個代碼織入的過程提成一個通用的工具:
function Interceptor(){
}
Interceptor.prototype.before = function(callContext, params){
console.log("before... ", callContext, params);
}
Interceptor.prototype.after = function(callContext, params){
console.log("after... ", callContext, params);
}
Interceptor.prototype.error = function(callContext, params){
console.log("error... ", callContext, params);
}
var InjectUtil = (function(){
function inject(obj, methodName, interceptor){
var targetFun = obj\[methodName\];
if(typeof targetFun == "function"){
var proxyFun = genProxyFun(targetFun, interceptor);
obj\[methodName\] = proxyFun;
}
}
function genProxyFun(targetFun, interceptor){
var proxyFunc = function(){
var ctx = this;
var result = null;
interceptor.before(ctx, arguments);
try{//歡迎加入全棧開發交流圈一起學習交流:864305860
result= targetFunc.apply(ctx, arguments);
}catch(e){
interceptor.error(ctx, arguments);
}finally{
interceptor.after(ctx, arguments);
}
return result;
};
return proxyFunc;
};
return {
inject:inject
}
})();
測試:
Person.prototype.show=function(){
console.log("id: "+this.id + " age: "+ this.age);
};
InjectUtil.inject(Person.prototype,"show",new Interceptor());
var p = new Person({
id:"test3",
age:3
});
p.show();
結語
> 感謝您的觀看,如有不足之處,歡迎批評指正。