2012-06-14 39 views
2

我有一個函數可以創建一個測試元素。在返回函數之前,我將對測試元素的引用取消,以幫助防止內存泄漏。但是closure compiler正在刪除它認爲不需要的那條線b/c(在兩種模式中)。是否有某種comment,我可以添加以防止行被刪除?如何防止Google Closure編譯器刪除一行

function isExample (testElem) { 
var bool; 
testElem = testElem || document.createElement('div'); 

// Do stuff in here to determine `bool` 
// ... 

// Then nullify the reference 
testElem = null; // The compiler removes this line. How do I make it keep it? 

return bool; 
} 

回答

5

這是不需要的。垃圾收集器也會這樣做,所以Google Closure Compiler將其刪除。

我不知道任何垃圾收集器,泄漏內存在這個,JS會有很大的問題,如果有。

請記住,JS有函數作用域,這意味着函數中定義的任何變量在執行離開函數後都會被垃圾回收。

這是垃圾收集器的基本功能之一,如果js引擎會泄漏內存,這將是嚴重的問題。

對於舊的IE泄漏,您可以嘗試通過在取消它之後添加testElement = []來解決編譯器的問題。

+0

內存泄漏在舊IE中是個問題。 jQuery和Modernizr都會使某些函數中的元素無效 - 這一定是有原因的。 – ryanve

+0

請注意,它不適用於創建閉包的函數,因爲變量必須保持活動狀態,因爲閉包在原始函數返回後仍可以訪問它。這是不是在OP的情況下,雖然,所以+1 :) – Esailija

+1

@ryanve它在舊版IE內存泄漏上刪除DOM元素的事件監聽器,而不是像這樣:-) –

2

在這種情況下,編譯器是正確的。但是,如果您在保持代碼方面死心塌地,那麼您需要使用帶引號的語法來導出值或使用接收器對象。

function sinkValue(x) { 
    sinkValue[' '](x); 
    return x; 
} 
sinkValue[' '] = function(){}; 

function isExample (testElem) { 
    var bool; 
    var obj = { 'elem': testElem || document.createElement('div') }; 

    // Do stuff in here to determine `bool` 
    // ... 

    obj['elem'] = null; 
    sinkValue(obj); 

    return bool; 
} 

引用語法既防止重命名和死代碼消除,所以你會否定任何對對象屬性的優化。在這種情況下,儘管您將對象的生命延伸到函數之外(這似乎與您的意圖相反)。

有沒有註釋來確切地指定你想要的。你可以看到在與此相關的討論:

編譯器做什麼打算,因爲它是刪除無用的代碼。

+1

乍得,對象是非轉義的,所以如果這確實起作用,它可能仍然會在未來被淘汰。使用全局窗口而不是obj可以工作,但肯定會超過kill。 – John

+1

是的,我很擔心這一點。這兩個看起來都是過分的。對於像這樣的情況,您似乎需要複製goog.reflect.sinkValue定義。我會適當修改答案。 –

相關問題