为什么将数据存储为元素的属性存在风险?

我继续阅读同样的事情:

“直接在DOM元素上存储属性值是有风险的,因为可能存在内存泄漏。”

但有人可以更详细地解释这些风险吗?

(根据属性,我假设您指的是DOM元素的属性。)

DOM元素的自定义属性是否安全?

有些浏览器在销毁时没有很好地清理DOM元素。 因此保留了对其他元素,相同元素或大量数据的引用,从而导致泄漏。 我相信这在较新的浏览器中已基本解决。

在任何情况下,在元素上存储少量数据都是无害的,并且可以非常方便,因此请用一粒盐警告。


使用jQuery的.data()是一种安全的替代方案吗?

不是特别。 使用jQuery的自定义数据存储来存储数据有其自身的内存泄漏潜力,不幸的是它们不仅仅影响旧的浏览器。

为了避免泄漏,您需要绝对确定在销毁元素时清理元素的.data() 。 当您使用jQuery来销毁元素时,这是自动的,但如果不这样做,您将会遇到影响每个浏览器的内存泄漏。


有哪些例子可能导致泄漏?

假设有一堆.data()链接到#foo元素。 如果我们使用jQuery方法删除元素,我们是安全的:

 $("#foo").remove(); // associated .data() will be cleaned automatically 

但是如果我们这样做,我们就会遇到跨浏览器兼容的漏洞:

 var foo = document.getElementById("foo"); foo.parentNode.removeChild(foo); 

或者如果#foo是其他元素的后代,其内容在没有jQuery的情况下被清除,那么问题也是如此。

 otherElement.innerHTML = ""; 

在这两种情况下,jQuery都不用于删除#foo ,因此它的.data()永久地与元素#foo ,并且我们的应用程序有泄漏。


所以,如果我从不直接使用DOM API,我会安全吗?

你更安全,但另一种方法是,如果我们加载多个DOM操作库。 考虑到jQuery帮助我们使用以下代码执行此操作:

 var $jq = jQuery.noConflict(); 

现在我们可以允许$引用prototypejsmootools ,jQuery由$jq引用。

麻烦的是那些其他库不会清理jQuery设置的数据,因为他们不知道它。

因此,如果jQuery在#foo上有一些数据,并且mootools用于销毁该元素,那么我们就会发生内存泄漏。


如果我从不在jQuery中使用.data()怎么办? 这会让我安全吗?

可悲的是没有。 jQuery使用相同的.data()机制来存储其他数据,比如事件处理程序。 因此,即使您从未调用.data()将某些自定义数据与元素相关联,您仍然可能会因上述示例而导致内存泄漏。

大多数情况下,您可能没有注意到泄漏,但根据代码的性质,它们最终会变得足够大而成为一个问题。

根据jQuery文档 :

在版本9之前的Internet Explorer中,使用.prop()将DOM元素属性设置为除简单原始值(数字,字符串或布尔值)之外的任何内容都可能导致内存泄漏(如果未删除该属性)(使用.removeProp( ))从文档中删除DOM元素之前。 要在没有内存泄漏的情况下安全地设置DOM对象的值,请使用.data()。