JavaScript面向切面編程

很多人都知道java,spring裏面有一個aop的切面編程,它利用了反射機制實現了。今天我們用js來實現一個模仿的,只是簡單的實現,你可以自行再添加自己的條件和完善:

function aop(obj,before,after,filter){
for (var fun in obj)
(function(){
if (filter(fun))return;
var _fun = obj[fun];
obj[fun] = function(){
before.apply(obj);
_fun.apply(obj,arguments);
after.apply(obj);
return obj;
}
})();
}


obj就是你需要截取的類,before是obj類方法運行之前需要執行的方法,當然你也可以寫個空方法,所有參數都不允許爲空,after就是obj類方法運行之後需要執行的方法,filter就是過濾obj類方法中不需要改變的方法。

由於平常寫代碼需要調試,這次用一個調試類來具一個例子,在引入這個代碼之前,需要引入jQuery.js,方便。^.^:

var FireBug = {
_on : false,
_CONSOLE_STYLE : {
"font-size" : "16px",
"font-weight" : "900",
"color" : "lightgreen",
"background" : "black",
"font-family" : "'microsoft yahei', arial"
},
_BODY_STYLE : {},
_stream : null,
_wrapper : $(document.createElement("div")).addClass("firebug").css("line-height","120%"),
_open : function(){
for(var css in this._CONSOLE_STYLE)
this._BODY_STYLE[css] = $("body").css(css);
this._stream = $("body").css(this._CONSOLE_STYLE);
this._on = true;
},
close : function(){
$("body").css(this._BODY_STYLE).children(".firebug").remove();
this._on = false;
},
print : function(param){
"object" === typeof param ? this.showObj(param) : this.log(param);
},
showObj : function(obj){
for(var p in obj)
this.log(p + " : " + obj[p]);
},
log : function(msg){
this._stream.append(this._wrapper.clone().html(msg||""));
},
warn : function(msg){
this._stream.append(this._wrapper.clone().css("color","red").html(msg||""));
},
type : function(param){
this.log(typeof param);
}
}


這個調試類中包含了判斷對象類型,打印信息,提示警告等。但是美中不足的就是不能鏈式調用。如果我們每一個方法最後都加一行返回代碼,後果不樂觀。所以用上面這個

方法:

aop(FireBug, 
function(){
if (!this._on)
this._open();
},
function(){
}, 
function(fun_name){
return /^_/.test(fun_name);
}
);

如此一來,內部加了下劃線的內部變量不受影響,而該改變的都改變了。再來幾個簡潔的快捷方式的調用:



window.F = FireBug;


function log(msg){
return ( typeof msg === "boolean" ) ?  
F.log(msg ? "true" : "false") :
F.log(msg);
}
function print(msg){return F.print(msg);}
function warn(msg){return F.warn(msg);}
function type(param){return F.type(param);}

做到這裏已經差不多可以看效果了:

我們可以正式的調用,記得頁面要加載完:F.log("Hello,World");或者直接調用log("Hello,World");都是可以的。


當然你可以進行連接調用:

log("Hello,World").warn("what a shit day!!!").log("It's a jok ^.^").print({name:'henry',age:100}).type("這是字符串類型,輸出string");




呵呵,有點意思啊!!!!歡迎來羣交流:55732875

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章