12

假设我有一个函数:

function a() {
    this.b = 1;
    this.set = setInterval(function() {console.log(this.b);}, 200);
}

因此,当调用 a.set() 时,将调用匿名函数。但这不起作用,因为在触发函数时 this 指向窗口对象。此外,使用 ab 也不是一个好主意,因为 a 可能有多个实例。

这个问题有什么好的解决方案?

4

6 回答 6

24

存储对 的引用this

function a() {
    var self = this;
    self.b = 1;
    self.set = setInterval(function() {console.log(self.b);}, 200);
}

您传递给的匿名函数可以setInterval访问其包含范围内的任何变量,即function a(). JS 闭包的魔力即使在a()完成后也能让这些变量保持活跃,并且每次调用a()都有自己的闭包。

于 2012-06-08T06:30:20.860 回答
11

既然我们现在有 ES6,我认为我们需要另一个答案:

使用箭头函数:

function a() {
  this.b = 1;
  this.set = setInterval(() => {console.log(this.b);}, 200);
}

与普通函数相反,箭头函数本身没有this上下文。这意味着您可以访问外部this.

于 2017-08-15T23:28:48.470 回答
6

这将是最干净的解决方案,因为大多数时候您实际上希望为连续的方法调用切换 this 上下文:

    // store scope reference for our delegating method
    var that = this;
    setInterval(function() {
        // this would be changed here because of method scope, 
        // but we still have a reference to that
        OURMETHODNAME.call(that);
    }, 200);
于 2014-11-05T14:46:42.700 回答
2

只需将您的this引用保存在其他变量中,window稍后不会被 -call 覆盖。稍后您可以使用该变量来引用您开始使用的对象。

function a() {
    this.b = 1;
    var that = this;
    this.set = setInterval(function() {console.log(that.b);}, 200);
}
于 2012-06-08T06:29:45.553 回答
0

在您的情况下,您可以简单地:

function a() {
    var _this = this;
    this.b = 1;
    this.set = setInterval(function () {
      console.log(_this.b);
    }, 200);
}

通常,我们也可以有一个辅助方法来Function.prototype.bind修复引用this

于 2012-06-08T06:29:48.783 回答
0

这个问题太老了,但我不喜欢这里的解决方案,因为这个想法主要是将实例附加到public

这是另一个可行的想法:

问题是,当从区间作为回调调用时,范围不在 inside this。但是,您可以通过定义一个 Function 变量来强制它。

function a() {
  var localCallback: () => {
    // access `this` as you will
    console.log(this);
  };
  this.timer = setInterval( localCallback, this.saveInterval );
}

希望这有帮助!

于 2019-01-24T08:56:32.050 回答