2012-11-07 72 views
1

對於此代碼:如何清理這個封閉參考

var myObj = { 
    callMeMaybe: function() { 
     var myRef = this; 
     var val = setTimeout(function() { 
      console.log('Time is running out!'); 
      myRef.callMeMaybe(); 
     }, 1000); 
    } 
}; 

myObj.callMeMaybe(); 
myObj = null; 

如果我們調用myObj.callMeMaybe(),然後調用MyObj中=空。 我們仍然不能取消callMeMaybe();無論如何解決這個問題?謝謝。

+0

你有沒有試過clearTimeout? http://www.w3schools.com/jsref/met_win_cleartimeout。asp – cbillowes

回答

-1

用新函數覆蓋callMeMaybe屬性,如果不介意TypeError,則覆蓋null

myObj.callMeMaybe(); 
myObj.callMeMaybe = function(){}; 

現在,當異步調用從setTimeout製成,它會調用虛函數。


如果你不想覆蓋函數,那麼只需在對象上設置一個標誌。

var myObj = { 
    callMeMaybe: function() { 
     var myRef = this; 
     var val = setTimeout(function() { 
      console.log('Time is running out!'); 
      if (!myRef.prevent) 
       myRef.callMeMaybe(); 
     }, 1000); 
    } 
}; 

myObj.callMeMaybe(); 
myObj.prevent = true; // will prevent the .callMeMaybe() in the setTimeout 

但要清楚,你不能明確 closure引用本身。對象是引用類型,JavaScript是按值傳遞的。

這意味着,當你這樣做:

var myRef = this; 

...你所做的對象引用的副本。因爲myRef是局部變量,所以不能從外部觸及。你可以做的最好的操作是引用的對象,或者使myRef變量可用於外部作用域。

...並忽略倒票選民。他們不瞭解JavaScript如何工作。

+0

這將不起作用,因爲'setTimeout'已經被調用,所以傳遞給它的函數已經被創建。 –

+0

@保羅斯:那是不正確的。 'setTimeout'回調函數調用對象引用中的'callMeMaybe',它將覆蓋'callMeMaybe'屬性。 –

+0

再次看看這個問題,'setTimeout'在日誌完成之後纔會使用'callMeMaybe',所以代碼仍然會執行。 –

0

您需要window.clearTimeoutval

var myObj = { 
    callMeMaybe: function() { 
     var myRef = this; 
     this.val = setTimeout(function() { // made val visible outside 
      console.log('Time is running out!'); 
      myRef.callMeMaybe(); 
     }, 1000); 
    } 
}; 

myObj.callMeMaybe(); 

window.clearTimeout(myObj.val); 
myObj = null; 
+0

這會導致整個'setTimeout'被取消,這不是問什麼問題。 –

0

clearTimeout()方法清除使用setTimeout()方法設置的計時器。 setTimeout()返回的ID值用作clearTimeout()方法的參數。

clearTimeout(id_of_settimeout); 

Number.MAX_VALUE是1.7976931348623157e + 308VALUE

我認爲這個問題可以通過clearTimeout循環1.7976931348623157e + 308VALUE時間來完成。

需要很長時間嗎?

或者您也可以通過

max_id_of_settimeout = setTimeout(null,0); 

然後循環獲得最大的id_of_settimeout回到

for (var i = max_id_of_settimeout;i>=0;i--){clearTimeout(i);} 

只是我的意見。

+0

爲什麼要清除頁面上的所有計時器? –

+0

,因爲我認爲沒有辦法**取消設置的定時器**,除非清除所有這些。 – whytobe