2012-06-08 30 views
8

假設有一個函數:我如何通過「本」,以窗口的setInterval

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

所以當a.set()被調用匿名函數會被調用。但是當這個函數觸發指向窗口對象時,這不會起作用。另外,使用a.b並不是一個好主意,因爲可能有多個a的實例。

什麼是解決這個問題的好方法?

+0

你爲什麼不使用'apply'或'call' https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/apply – Deeptechtons

+0

@deeptechtons - 我不認爲'應用'或'call'對於這個問題有任何用處,但也許你可以在答案中解釋你的想法? – nnnnnn

+0

@nnnnnn問題絕對是「我如何改變函數內部的上下文」的問題。這是用appy或call調用解決的。但這可能是矯枉過正。 – Deeptechtons

回答

16

商店this參考:您傳遞給setInterval

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

匿名函數可以訪問任何變量,它包含的範圍,即,function a()任何局部變量。即使在a()完成之後,JS閉包的魔力仍然使這些變量保持活躍狀態​​,並且每次調用a()都會自行關閉。

+0

是的,我見過這樣的例子,但這正是讓我困惑的原因。假設「a」在200ms事件觸發之前完成,變量self似乎應該在當時銷燬。如果不是,那麼什麼時候它會被銷燬?間隔清除後? – NSF

+0

正如我在我的回答中所提到的,在包含函數完成後,內部函數可以訪問其包含函數_even範圍內的變量。在這種情況下,'setInterval'繼續保持對內部函數的引用,所以即使在'a()'完成後它仍然可以繼續調用它。直到間隔被清除,引用將保持活動狀態,並且變量將保持活動狀態。請注意,由於JS在單個線程上運行,所以'a()'將在間隔被觸發前(無論間隔多短)完成_definitely_完成。谷歌「JavaScript關閉」瞭解更多信息。 – nnnnnn

+0

有道理。謝謝。 – NSF

2

只需在其他變量中保存您的this引用即可,稍後不會被window覆蓋。稍後,您可以使用該變量來引用他開始使用的對象。

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

在你的情況,你可以簡單地說:

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

通常情況下,我們還可以有一個輔助方法Function.prototype.bind修復this參考。

4

這將是最乾淨的解決方案,因爲大部分的時間你真的想切換此背景下爲您的連續方法調用:

// 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); 
3

因爲我們有ES6現在,我認爲我們需要另外一個答案在這裏:

使用箭頭功能:

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

箭頭的功能,相反正常功能,不具備對this背景下他們的擁有。這意味着您可以訪問外部this

+1

ES6已經將我的語法再次減少到幾乎沒有!謝謝! – HoldOffHunger