假設有一個函數:我如何通過「本」,以窗口的setInterval
function a() {
this.b = 1;
this.set = setInterval(function() {console.log(this.b);}, 200);
}
所以當a.set()被調用匿名函數會被調用。但是當這個函數觸發指向窗口對象時,這不會起作用。另外,使用a.b並不是一個好主意,因爲可能有多個a的實例。
什麼是解決這個問題的好方法?
假設有一個函數:我如何通過「本」,以窗口的setInterval
function a() {
this.b = 1;
this.set = setInterval(function() {console.log(this.b);}, 200);
}
所以當a.set()被調用匿名函數會被調用。但是當這個函數觸發指向窗口對象時,這不會起作用。另外,使用a.b並不是一個好主意,因爲可能有多個a的實例。
什麼是解決這個問題的好方法?
商店this
參考:您傳遞給setInterval
function a() {
var self = this;
self.b = 1;
self.set = setInterval(function() {console.log(self.b);}, 200);
}
匿名函數可以訪問任何變量,它包含的範圍,即,function a()
任何局部變量。即使在a()
完成之後,JS閉包的魔力仍然使這些變量保持活躍狀態,並且每次調用a()
都會自行關閉。
是的,我見過這樣的例子,但這正是讓我困惑的原因。假設「a」在200ms事件觸發之前完成,變量self似乎應該在當時銷燬。如果不是,那麼什麼時候它會被銷燬?間隔清除後? – NSF
正如我在我的回答中所提到的,在包含函數完成後,內部函數可以訪問其包含函數_even範圍內的變量。在這種情況下,'setInterval'繼續保持對內部函數的引用,所以即使在'a()'完成後它仍然可以繼續調用它。直到間隔被清除,引用將保持活動狀態,並且變量將保持活動狀態。請注意,由於JS在單個線程上運行,所以'a()'將在間隔被觸發前(無論間隔多短)完成_definitely_完成。谷歌「JavaScript關閉」瞭解更多信息。 – nnnnnn
有道理。謝謝。 – NSF
只需在其他變量中保存您的this
引用即可,稍後不會被window
覆蓋。稍後,您可以使用該變量來引用他開始使用的對象。
function a() {
this.b = 1;
var that = this;
this.set = setInterval(function() {console.log(that.b);}, 200);
}
在你的情況,你可以簡單地說:
function a() {
var _this = this;
this.b = 1;
this.set = setInterval(function() {
console.log(_this.b);
}, 200);
}
通常情況下,我們還可以有一個輔助方法Function.prototype.bind
到修復的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);
因爲我們有ES6現在,我認爲我們需要另外一個答案在這裏:
使用箭頭功能:
function a() {
this.b = 1;
this.set = setInterval(() => {console.log(this.b);}, 200);
}
箭頭的功能,相反正常功能,不具備對this
背景下他們的擁有。這意味着您可以訪問外部this
。
ES6已經將我的語法再次減少到幾乎沒有!謝謝! – HoldOffHunger
你爲什麼不使用'apply'或'call' https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/apply – Deeptechtons
@deeptechtons - 我不認爲'應用'或'call'對於這個問題有任何用處,但也許你可以在答案中解釋你的想法? – nnnnnn
@nnnnnn問題絕對是「我如何改變函數內部的上下文」的問題。這是用appy或call調用解決的。但這可能是矯枉過正。 – Deeptechtons