$ .proxy,bind,call,apply之间的区别

时间:2013-06-09 22:17:31

标签: javascript jquery object this anonymous-function

旧方式:

var self = this;    
setTimeout(function(){
  console.log(self);
}, 5000);

使用jQuery:

setTimeout($.proxy(function(){
  console.log(this);
}, this), 5000);

使用bind:

setTimeout((function(){
  console.log(this);
}).bind(this), 5000);

通过电话:

setTimeout((function(){
  console.log(this);
}).call(this), 5000);

似乎申请也有效:

setTimeout((function(){
  console.log(this);
}).apply(this), 5000);

http://jsfiddle.net/SYajz/1/

我想知道这些方法之间是否存在任何不那么明显的差异

2 个答案:

答案 0 :(得分:9)

是的,所以我们在这里有三种调用函数的方式。它们都是解决 context 问题的方法,即this关键字将具有不同的值,具体取决于函数的调用方式。

混叠

var self = this;    
setTimeout(function(){
  console.log(self);
}, 5000);

这是一种非常简单的方法。它只是设置一个不会在函数中被覆盖的新变量。该值已关闭,因此在超时后调用该函数时,self将是您所期望的。

结合

setTimeout($.proxy(function(){
  console.log(this);
}, this), 5000);

setTimeout((function(){
  console.log(this);
}).bind(this), 5000);

这两个功能具有相同的结果。这是因为$.proxybind完全相同。但是,bind是一种新语法,不受某些旧版浏览器的支持。

这是通过永久性和#34;绑定"函数的上下文。这意味着,无论函数被调用,this的值将始终是bind的第一个参数的值。

call / apply

setTimeout((function(){
  console.log(this);
}).call(this), 5000);

setTimeout((function(){
  console.log(this);
}).apply(this), 5000);

同样,这两个功能是相同的。 callapply之间的唯一区别是其他参数发送到函数。 call需要一个列表(例如fn.call(context, param1, param2)),而apply需要一个数组(fn.apply(context, [param1, param2]))。

这两个函数的作用是使用指定的特定上下文调用函数。

但是,这些功能都不能满足您的需求。它们都使用特定的上下文立即调用该函数,而不是等待5秒钟。这是因为callapply的工作方式与()类似:代码会立即执行。

结论

哪种方法更合适取决于您的任务。对于简单的操作,别名可能很好地完成工作。但值得记住的是,这引入了另一个变量,并且上下文无法在呼叫时设置。其他方法在不同情况下也有其优势,特别是在编写用户提供回调函数的库时。

答案 1 :(得分:4)

使用$.proxy.bind(),您将创建一个新this值绑定到您提供的值的新函数。这就是传递给setTimeout()的函数。


使用.call().apply()您立即调用该功能,因此它不会等待计时器。

对于那些使用计时器的人,您需要返回一个函数来关闭引用所提供的this值的变量,并在给定引用的console.log()的情况下调用this 1}}。

setTimeout((function(){
  var that = this;
  return function() {
      console.log(that);
  }
}).call(this), 5000);