jQuery.proxy()方法的两种使用方法:
该方法作用是改变函数作用域(依靠apply方法实现)
方式一:jQuery.proxy(function,context)
该方式作用是将function的作用域修改为context,即function中的this值指向context,与apply作用相同。
var name = "Jack";
var person = {
name:"Rose"
}
function test(){
console.log(this.name);
}
test(); // "Jack"
$.proxy(test,person)(); // "Rose",与test.apply(person)作用相同
方式二:jQuery.proxy(context,name)
第二种方式主要应用于对象,第二个参数必须为第一个参数的属性且必须是字符串。
为了演示第二种方式我们添加 一个button,点击button输出name值。
<button>click</button>
<script type="text/javascript">
var person = {
name:"Rose",
clickFn:function(event){
console.log(this.name);
}
}
$("button").click(person.clickFn);
</script>
此时点击button,控制台打印为空,因为此时clickFn中的this指向了button,此时button中是没有name属性,如果我们在button中添加一个name="button"属性,则会打印“button”,现在我们将click事件改为如下方式。
$("button").click($.proxy(person,"clickFn")); // 控制台打印“Rose”
// 或使用方式一:
$("button").click($.proxy(person.clickFn,person)); // 控制台打印“Rose”
通过jQuery.proxy方法将clickFn中的this由指向button改向指向person。
现在我们看一下jQuery是如何实现的,下面为jQuery源码:
jQuery.proxy = function( fn, context ) {
var tmp, args, proxy;
if ( typeof context === "string" ) {
tmp = fn[ context ];
context = fn;
fn = tmp;
}
// Quick check to determine if target is callable, in the spec
// this throws a TypeError, but we will just return undefined.
if ( !isFunction( fn ) ) {
return undefined;
}
// Simulated bind
args = slice.call( arguments, 2 );
proxy = function() {
return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
};
// Set the guid of unique handler to the same of original handler, so it can be removed
proxy.guid = fn.guid = fn.guid || jQuery.guid++;
return proxy;
};
可以看出jQuery是通过判断第二个参数的类型来区分这两种方式的,所以第二种使用方式的第一个参数必须为对象,第二个参数必须是第一个参数的字符串形式的属性;两种方式最终通过apply方法实现作用域的改变。
*注:jQuery.proxy()中args是从第三个位置截取的,也就是说jQuery.proxy方法不止可以传2个参数,那么其他参数是什么呢。现在我们让click事件可以传递参数,将第二种方式修改一下:
var person = {
name:"Rose",
clickFn:function(age){
console.log(this.name+":"+age);
}
}
$("button").click($.proxy(person,"clickFn",12)); // Rose:12
$("button").click($.proxy(person.clickFn,person,13)); // Rose:13
也就是说jQuery.proxy()中第二个参数之后的参数可作为被作用函数的参数进行传递。
总结:
jQuery.proxy()依靠apply改变函数作用域,从而改变this的值。