2017-07-31 73 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裏面的代碼,如果你使用這個關鍵字裏面然後兩個行爲不同的功能和箭頭功能 –