当某一个事件由一个元素触发,但与此同时又需要另外一个对象进行关联动作的时候,就非常适合使用代理。jQuery的proxy方法,可以将回调函数绑定在特定的context上。比如,点击某个按钮,让另外一个元素显示,就可以通过如下代码来实现。
$(someSelector).click($.proxy($(targetSelector), 'show')));
proxy的实现机制是怎样的呢?其源码如下:
jQuery.extend({
// 全局的id计数器
guid: 1,
proxy: function( fn, context ) {
var tmp, args, proxy;
/*
* 正常情况下,fn是待执行的函数
* 如果context是字符串,那么proxy会认为fn是一个对象,fn[content]是实际需要执行的函数,这种情况下将两者进行交换,以便后续代码一致
*/
if ( typeof context === "string" ) {
tmp = fn[ context ];
context = fn;
fn = tmp;
}
// 如果fn不是函数,则直接退出
if ( !jQuery.isFunction( fn ) ) {
return undefined;
}
// 获取绑定的参数信息(如果有的话)
args = slice.call( arguments, 2 );
// 将contenxt保存在闭包中,以便后续调用
proxy = function() {
// 在调用之前,将具体调用时的参数拼接到绑定时的参数列表之后
return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
};
// 设置guid,如果fn存在guid,就直接使用,否则获取jQuery的guid值,并使之自增
proxy.guid = fn.guid = fn.guid || jQuery.guid++;
return proxy;
}
});
代码还是比较简单易懂的,获取到proxy之后,只要在调用proxy(some,args),就会执行fn,并优先使用context作为执行时的this(若context为空则使用jQuery对象),然后将实际执行的参数拼接到绑定时候的参数列表之后,如果有的话。