很多人都知道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