之前的2篇文章在讨论prototypejs库的继承实现方式、$super和_super过程中,我看到了Function#wrap()这个很有意思的API。这篇文章学习下如何使用Function#wrap(),以及它的源码。
我们先看下官方对这个API的说明:也就是说wrap()可以用来实现类似AOP编程的效果。
[[Function#wrap]] distills(提炼) the essence of aspect-oriented programming(AOP)
into a single method, letting you easily build on existing functions by
specifying before and after behavior, transforming the return value, or
even preventing the original function from being called.
function sayName(name)
{
console.log("original method="+name);
return "return="+name;
}
// prototypejs将wrap加入到了Function.prototype中
var wrapper = sayName.wrap(function(callOriginal, before_or_after, msg, name){
if(before_or_after == "before")
{
console.log(msg);
return callOriginal(name);
}
else if(before_or_after == "after")
{
var result = callOriginal(name);
console.log(msg);
return result;
}
else
{
console.log(msg);
var result = callOriginal(name);
console.log(msg);
return result;
}
});
console.log(wrapper("before","morning", "aty"));
console.log(wrapper("after","afternoon", "qun"));
console.log(wrapper("both","welcome", "xy"));
prototypejs库将wrap方法添加到了Function.prototype对象中,所以每一个函数对象都会获得wrap方法。Function#wrap()的入参是一个函数,返回值也是一个函数。入参的函数签名具有如下性质:
// callOriginal这个函数是原始函数(未经过包装处理)
// arg1 arg2...是调用函数需要传递的参数
function wrapper(callOriginal[, arg1[, arg2]...])
{
}