JavaScript是怎样AOP实现?

更新日期: 2018-11-09阅读: 2.3k标签: AOP

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 
}); 
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 {
				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();



链接: https://fly63.com/article/detial/1307

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!