js中的 AOP

时间:2023-03-09 00:14:23
js中的 AOP

原文 :http://blog.csdn.net/notejs/article/details/8770575

面向切面的编程(AOP)还是有点意思的,可以在不修改原有代码的情况下增加新功能。有一些js框架实现AOP功能,但是有些时候我们并不能依赖于框架写程序(框架可能很笨重),我们需要自己实现一些适合我们的功能模块。下面是我自己实现的js AOP,实现了before和after功能,仅供抛砖。

如下是aspect.js,是实现AOP的全过程

(function(window, undefined){
function aspect(type){
return function(target, methodName, advice){
var exist = target[methodName],
dispatcher; if( !exist || exist.target != target ){
dispatcher = target[methodName] = function(){
// before methods
var beforeArr = dispatcher.before;
var args = arguments;
for(var l = beforeArr.length ; l--; ){
args = beforeArr[l].advice.apply(this, args) || args;
}
// target method
var rs = dispatcher.method.apply(this, args);
// after methods
var afterArr = dispatcher.after;
for(var i = 0, ii = afterArr.length; i < ii; i++){
rs = afterArr[i].advice.call(this, rs, args) || rs;
}
// return object
return rs;
} dispatcher.before = [];
dispatcher.after = []; if( exist ){
dispatcher.method = exist;
}
dispatcher.target = target;
} var aspectArr = (dispatcher || exist)[type];
var obj = {
advice : advice,
_index : aspectArr.length,
remove : function(){
aspectArr.splice(this._index, 1);
}
};
aspectArr.push(obj); return obj;
};
} window.aspect = {
before : aspect("before"),
after : aspect("after")
}; return window.aspect; })(window);
// 以下是测试代码:
var as = window.aspect; var obj = {
url:"",
get : function(key){
return this["key"];
},
set : function(key, value){
this["key"] = value;
}
}; var h1 = as.before(obj, "set", function(key, value){
// 返回一个数组可以修改参数
value += " before-1 ";
//console.log(value);
return [key, value];
}); var h2 = as.before(obj, "set", function(key, value){
// 没有返回值则参数不会变化
value += " before-2 ";
//console.log(value);
}); obj.set("url", "http://mojijs.com");
console.log( obj.get("url") ); var h3 = as.after(obj, "get", function(value){
// 没有返回值不会修改原函数的返回值
value += " after-1 ";
//console.log(value);
}); var h4 = as.after(obj, "get", function(value){
// 有返回值会修改原函数的返回值
value += " after-2 ";
//console.log(value);
return value;
}); console.log( obj.get("url") ); h1.remove(); // 删除切面方法
h4.remove(); // 删除切面方法 obj.set("url", "http://baidu.com");
console.log( obj.get("url") );

  

==== 2013.04.12 update

本程序已经略做修改并提交github(https://github.com/notejs/aop),现在可同时支持浏览器和node.js环境。

浏览器环境可以通过window.aop使用。

node.js环境安装方法为npm install node-aop。