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。

原文地址:https://www.cnblogs.com/oxspirt/p/5432368.html