2012-04-04 22 views

回答

12

當您將DOM對象的引用作爲該DOM對象的屬性放入DOM對象時,循環引用問題發生在某些瀏覽器中。然後,你有兩個DOM對象指向對方。使用自定義屬性移除DOM對象不會清除該自定義屬性。垃圾收集器不是那麼聰明,並沒有意識到這個DOM引用不會被計數,所以它會被卡住,並且有幾種方法會導致泄漏。

.data()解決了這個問題,因爲.data()數據不在DOM對象上。它只是一個JavaScript數據結構,可以通過唯一的字符串ID與DOM對象關聯。

的一個令人困惑的這一部分是,當你與.data("key")閱讀和key沒有在JavaScript .data()數據結構中發現,那麼只有到那時,jQuery將查找名爲"data-key"的DOM對象的屬性。但是,只要使用.data("key", "myData")編寫,它就不會寫入DOM對象,只寫入JavaScript數據結構。

因此,因爲.data()從不將數據寫入DOM對象,所以某些瀏覽器不能使用這些類型的循環引用。

關於.data()數據結構還有一些其他有用的信息。當您使用jQuery的.remove()從DOM中刪除元素或當您致電$(elem).html("new html")時,jQuery將清除所有已刪除項目上的.data()數據。這是一個不會將jQuery與純javascript結合的例子。如果您使用的是.data(),那麼您應該始終使用jQuery函數從DOM中刪除項目,以便.data()得到適當的清理。否則,你可以通過這種方式獲得內存泄漏(.data()數據可能會泄漏,並且.data()中引用的任何已刪除的DOM對象都可能泄漏。但是,如果只使用jQuery方法從DOM中刪除項目(包括替換innerHTML因爲你刪除與普通的JavaScript,jQuery的DOM元素

// suppose elem is a DOM element reference 

// store some data in jQuery's data storage on behalf of a DOM element 
$(elem).data("someKey", "someValue"); 

// remove DOM element with plain Javascript 
elem.parentNode.removeChild(elem); 

:),然後jQuery將進行相應的清理事情搞砸,不會有泄漏

因此,舉例來說,這將創建一個內存泄漏。沒有機會清理以前存儲的數據,DOM元素本身將被垃圾收集,但您以前的值紅色現在在jQuery的存儲中成爲孤兒,實質上是一個「泄漏」,因爲它可能永遠不會被清除。在另一方面,如果你這樣做:

$(elem).data("someKey", "someValue"); 
$(elem).remove(); 

然後,jQuery將看到您刪除的DOM元素,也將清除您存儲與.data()數據。

看看它是如何工作的一個相當簡單的方法是創建一個帶有非最小化版本的jQuery的幾行腳本,然後在調試器中調用$(elem).data("key", "whatever")並觀察其工作原理。

+0

請您舉例說明您對第5段的解釋嗎? – 2016-10-06 08:49:27

+0

@ techloris_109 - 已添加示例。 – jfriend00 2016-10-06 20:21:47