2010-02-05 45 views
0

我想知道如果我可以做一些清理例程,將自動獲取超時/間隔。考慮這一點:通過setInterval/setTimeout訪問eval'd代碼

var timeout = setInterval(function dimitar() { 
    console.log("hi!"); 
}, 1000); 

console.log(window); 

我有一個通過窗口看,無法找到任何引用傳遞的函數。對超時的引用在那裏,果然。那麼這個功能在哪裏「生活」在這裏?它是否啓動了一個js解釋器的新實例來評估/運行/保留代碼?你怎樣才能訪問它關於超時uid?

我知道我可以討好的setInterval函數,並讓它始終存儲參考到一個數組,然後我就可以遍歷和明確的,但很好奇,如果有這樣

回答

1

那麼,這是否「活」的功能嗎?

超時/間隔隊列是內容JavaScript無法訪問的內部實現細節。它保留對傳遞到setInterval的函數的引用,但它不是您可見的引用。

順便說一句,你通常應該避免使用命名的內聯函數表達式。雖然在這個示例代碼中可能沒問題,但IE的JScript有一些嚴重的基本錯誤,如果你不小心的話可能會讓你感到不適。堅持命名函數語句(function dimitar() { ... } ... setInterval(dimitar, 1000))或匿名內聯函數表達式(setInterval(function() { ... }))。

它啓動了一個新的js解釋器實例來評估/運行/保留代碼嗎?

不,這是相同的解釋器和隊列甚至可以在JavaScript中實現。但是它背後的變量隱藏在調用者之外。

你怎樣才能訪問它相對於超時uid?

超時ID在設計上完全不透明。唯一定義的接口可以處理任何事情,即clearTimeout/clearInterval調用。沒有接口提供從超時ID獲取功能。

+0

感謝您的解釋,現在更清楚 - 換句話說,我需要保留並清理引用。我只把名字函數dimitar放在那裏,所以我可以在firebug中搜索它。 – 2010-02-05 11:45:21

+0

'clean'在刪除超時'onunload'以儘量避免內存泄漏?這隻適用於IE6。 (即使這樣,我並不完全確定超時參與IE臭名昭着的本地/主機對象引用循環,但沒有經過測試。) – bobince 2010-02-05 12:20:26

+0

我剛剛在mootools中創建了這個 - http://mootools.net/shell/judGJ /是的,避免由於可能已經運行的代碼造成的內存泄漏不是一個壞主意,imo - 特別是對於IE – 2010-02-05 12:28:22

2

功能,你自然的方式在你的例子中創建的是使用命名函數表達式。該名稱僅在該功能中可用。否則,它的行爲與匿名函數相同:您尚未將其分配給變量,因爲它不是函數聲明,所以它不會在封閉範圍中創建dimitar變量。下面的文章可能是有用的:http://yura.thinkweb2.com/named-function-expressions/

沒有eval類型的事情發生:你剛剛通過一個函數的引用傳入window.setInterval。之後不能檢索此函數,除非先前已將其指定給變量,或者它是對由函數聲明定義的函數的引用。

如果你想保持周圍的函數的引用,它只是第一個變量保存它的問題:

var dimitar = function() { 
    console.log("hi!"); 
}; 

window.setInterval(dimitar, 1000); 
+0

感謝您的意見 - 正如我所說 - 我只把dimitar放在那裏,所以我可以在螢火蟲內搜索它。對'window.dimitar'的引用不是setInterval實例正在運行的引用。如果你使用'window.dimitar = null;'控制檯將繼續運行,因爲已經傳遞了該函數。 – 2010-02-05 11:46:45