2016-11-17 14 views
1

我一直在閱讀了關於JS的最佳做法和常見的錯誤,我碰到這段代碼從https://www.toptal.com/javascript/10-most-common-javascript-mistakes這個js代碼如何泄漏內存?

var theThing = null; 
var replaceThing = function() { 
    var priorThing = theThing; // hold on to the prior thing 
    var unused = function() { 
     // 'unused' is the only place where 'priorThing' is referenced, 
     // but 'unused' never gets invoked 
     if (priorThing) { 
      console.log("hi"); 
     } 
    }; 
    theThing = { 
     longStr: new Array(1000000).join('*'), // create a 1MB object 
     someMethod: function() { 
      console.log(someMessage); 
     } 
    }; 
}; 

我試着輸入這個代碼到控制檯,並呼籲replaceThing()多次,真不夠,即使在GC之後,Chrome任務管理器中的內存使用也會增加。

關閉unused保留對priorThing的引用,從而使其不符合GC的條件。但是:

當執行 priorThing = theThing
  1. ,不會在unused關閉參考改變以及對theThing
  2. 即使#1不是這樣,當執行replaceThing完成時,是否應該不會變量unused超出範圍?

回答

1

是有內存泄漏。這是因爲通過在Javascript中實現閉包的方式。每個函數對象都有一個指向代表其詞彙範圍的字典式對象的鏈接。 IF A VARIABLE IS USED IN ONE CLOSURE, IT ENDS UP IN THE LEXICAL SCOPE SHARED BY ALL OTHER CLOSURES IN THAT SCOPE。在這種情況下,我們在同一範圍內有兩個關閉theThingunused。在unused中使用priorThing,現在priorThing是閉包中的一個變量,就像unused未被調用一樣,將意味着priorThing也在theThing閉包的範圍內。所以priorThing將不會在replaceThing返回後收集垃圾。

1)當priorThing = theThing執行舊theThing值被存儲到priorThing所以unused舊指theThing不新創建的一個

+0

我試圖尋找在控制檯的功能範圍。我的理解是正確的:當創建Thing中的someMethod閉包時,它保留對未使用的引用,該引用本身保留對priorThing的引用。 priorThing本身包含了以前版本的someMethod,而對於以前版本的未使用,形成了一個引用鏈回到第一個對象? –

+0

耶,正確理解 – henrybbosa

+0

以及它的一個棘手的部分javascript – henrybbosa