9

老办法:

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

使用 jQuery:

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

绑定:

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

有电话:

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

似乎 apply 也有效:

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

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

我想知道这些方法之间是否有不那么明显的区别

4

2 回答 2

9

对,所以我们在这里有三种调用函数的方式。它们都是解决上下文问题的方法,即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但是,它是一种新语法,一些旧浏览器不支持。

这是通过将上下文永久“绑定”到函数来实现的。这意味着,无论函数如何调用, 的值this始终是 的第一个参数的值bind

call/apply

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

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

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

这两个函数所做的就是调用指定特定上下文的函数。

但是,这些功能都不能满足您的需求。他们都在特定的上下文中立即调用该函数,而不是等待 5 秒钟。那是因为callapply工作就像():代码立即执行。

结论

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

于 2013-06-09T22:27:57.920 回答
4

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


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

对于那些使用计时器的人,您需要返回一个函数,该函数关闭引用提供的this值的变量,并调用console.log()给定的 referenced this

setTimeout((function(){
  var that = this;
  return function() {
      console.log(that);
  }
}).call(this), 5000);
于 2013-06-09T22:20:18.927 回答