2017-07-31 71 views
1

这是我用来使用window.setinterval递增intVariable值的代码。与箭头函数相混淆javascript

var Arrow = (function() { 
 
    function Arrow() { 
 
     this.intVariable = 1; 
 
     this.itemId = -1; 
 
     this.interval = 25; 
 
    } 
 
    Arrow.prototype.activateTimer = function() { 
 
     if (this.itemId === -1) { 
 
      window.setInterval(this.showTimer(), this.interval); 
 
     } 
 
    }; 
 
    Arrow.prototype.showTimer = function() { 
 
     this.intVariable += this.interval; 
 
     console.log(this.intVariable); 
 
    }; 
 
    return Arrow; 
 
}()); 
 
var arrow = new Arrow(); 
 
arrow.activateTimer();

当我使用下面一行显示计时器函数被调用一次

window.setInterval(this.showTimer(), this.interval); 

但是,当我将其更改为:

window.setInterval(() => this.showTimer(), this.interval); 

它完美。

需要一些帮助,为什么它使用箭头功能。

回答

1

你应该提供的功能区间,而不是函数的返回。

每当你写window.setInterval(this.showTimer(), this.interval); 其实你正在做这个

var returnValue = (function() { 
    this.intVariable += this.interval; 
    console.log(this.intVariable); // You get your log for once 
})() // -> null 
window.setInterval(returnValue/*null*/, this.interval); 

然后setInterval试图调用每个this.intervalnull,这不会给你在控制台上的错误。

但是当你用箭头() => this.showTimer()调用它的意思是:

var returnValue = function() { 
    this.showTimer(); 
} // -> Function 
window.setInterval(returnValue/*Function*/, this.interval); 

您提供了一个功能区间。


而且还如果你忘了你的功能结合到this范围,你将无法访问你的箭范围。因此,您可能会看到很多NaN s

setInterval尝试调用您的注册函数,其全局范围是window。所以当你在你的函数中写入this时,它会以thiswindow。因此,无论何时尝试记录this.intVariable,它都会尝试记录未定义的window.intVariable

所以我们应该把我们的函数绑定到当前对象的作用域。因此,无论何时使用this,您的范围都将绑定到当前对象(箭头)。你会得到你当前的箭头intVariable

但是,只要您编写了() =>,您就可以创建类似上面的匿名函数,并且您已将其作用域连接到对象中。所以你不需要额外的绑定。

这里是您的解决方案

var Arrow = (function() { 
     function Arrow() { 
      this.intVariable = 1; 
      this.itemId = -1; 
      this.interval = 25; 
     } 
     Arrow.prototype.showTimer = function() { 
      this.intVariable += this.interval; 
      console.log(this.intVariable); 
     }; 
     Arrow.prototype.activateTimer = function() { 
      if (this.itemId === -1) { 
       window.setInterval(this.showTimer.bind(this), this.interval); 
      } 
     }; 
     return Arrow; 

}()); 
var arrow = new Arrow(); 
arrow.activateTimer(); 

这里是一个fiddle

+0

是的,这工作。但我很困惑,我已经如何使用这个引用,然后有什么区别做了绑定(这)。也如果使用箭头方法like()=> showtimer()那么它也在工作。所以我需要知道为什么这两种方法工作/ –

+0

@yashshukla解释更多的细节,编辑答案。 –

+0

我已经理解了70%,但仍然困惑于此,()=>和绑定(这)不完全确定的功能。你知道任何书籍或博客,我可以找到这方面的好消息吗?非常感谢您的帮助 –

2

你可以直接使用函数引用(不使用括号)

window.setInterval(this.showTimer, this.interval); 

通过使用一个函数调用,

window.setInterval(this.showTimer(), this.interval); 
//        ^^ 

您插入函数调用,而不是函数本身的结果。

当您使用

window.setInterval(() => this.showTimer(), this.interval); 

插入一个功能,而不实际调用它。

+0

是什么在有和没有parenthasis调用的区别? –

+0

如果我没有括号的电话它日志NAN –

0
window.setInterval(() => this.showTimer(), this.interval); 

就像

window.setInterval(function() {this.showTimer()}, this.interval);

window.setInterval(this.showTimer(), this.interval);没有工作,因为你只需要通过this.showTimer但你调用它的飞行

+0

这给了我NAN在日志 –

+0

可能是因为showTimer里面的代码,如果你使用这个关键字里面然后两个行为不同的功能和箭头功能 –