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();
动态的将代码切入到指定的方法、指定位置上的编程思想就是面向切面的编程。代码只有两种,一种是逻辑代码、另一种是非逻辑代码。
主要就是两个函数,在Function的原型上加上before与after,作用就是字面的意思,在函数的前面或后面执行,相当于无侵入把一个函数插入到另一个函数的前面或后面,应用得当可以很好的实现代码的解耦,js中的代码实现如下
以前学习java的Spring框架时,这是个很强大的东西,用于实现调用者和被调用者之间的解耦。虽然在JS中也提供了call与apply动态改变调用者,但在复杂的UI组件中,这是远远不够了。
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!