據我瞭解,在JavaScript中的內存管理是由引用計數完成 - 而一個對象的引用仍然存在,也不會被釋放。這意味着在單個頁面應用程序中創建內存泄漏是微不足道的,並且可能導致來自java背景的那些內存泄漏。這不是特定於JQuery的。以下面的代碼爲例:
function MyObject = function(){
var _this = this;
this.count = 0;
this.getAndIncrement = function(){
_this.count++;
return _this.count;
}
}
for(var i = 0; i < 10000; i++){
var obj = new MyObject();
obj.getAndIncrement();
}
在看內存使用情況之前,這看起來很正常。由於「_this」指針,MyObject的實例從不釋放,而頁面處於活動狀態(增加i的最大值以更顯着地看到它)。 (在老版本的IE中,它們從未被釋放,直到程序退出。)由於JavaScript對象可能在框架之間共享(我不建議嘗試這種方式,因爲它是嚴重的脾氣)。有時甚至在現代瀏覽器中javascript對象可能比他們想要的要長很多。
jQuery中的情況下,參照通常存儲保存DOM搜索的開銷 - 例如:由於
function run(){
var domObjects = $(".myClass");
domObjects.click(function(){
domObjects.addClass(".myOtherClass");
});
}
此代碼將堅持以domObject(及其全部內容)永遠,在回調函數中引用它。
如果jquery的編寫者在內部錯過了這樣的實例,那麼庫本身就會泄漏,但更多的時候是客戶端代碼。
function run(){
var domObjects = $(".myClass");
domObjects.click(function(){
if(domObjects){
domObjects.addClass(".myOtherClass");
domObjects = null;
}
});
}
或再次執行查找:
function run(){
$(".myClass").click(function(){
$(".myClass").addClass(".myOtherClass");
});
}
一個好的經驗法則是要
第二個例子可以通過顯式清除當不再需要它的指針定注意定義回調函數的位置,並儘可能避免太多嵌套。
編輯:作爲由Erik的評論指出,你也可以使用this指針,以避免unnescessary DOM查找:
function run(){
$(".myClass").click(function(){
$(this).addClass(".myOtherClass");
});
}
下面是一個例子:http://jsfiddle.net/qTu6y/8/您可以在探查器中使用Chrome的「Take a heapshot」來查看該代碼塊的每次運行都消耗大約20MB的RAM。 (在測試時,我確實碰到了「腳本在Chrome上使用了太多內存錯誤」) – Raynos
對於「我們這些來自Java背景的人」......以及清晰的解釋。 – Thimmayya
$(this).addClass在最後一種情況下性能會更好,因爲'this'代表一個核心JS DOM元素集合(這是JQuery對象通常使用適配器樣式模式包裝的東西),JQ不必在