我一直在读同样的东西:
“直接在 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()
与元素永久解除关联,并且我们的应用程序存在泄漏。
因此,如果我从不直接使用 DOM API,我是否安全?
你更安全,但另一种可能发生的方式是如果我们加载多个 DOM 操作库。考虑到 jQuery 使用以下代码帮助我们做到这一点:
var $jq = jQuery.noConflict();
现在我们可以允许$
引用prototypejs
or了mootools
,jQuery 被引用了$jq
。
问题是那些其他库不会清理 jQuery 设置的数据,因为他们不知道。
因此,如果 jQuery 上有一些数据#foo
,并且mootools
用于销毁该元素,我们就会有内存泄漏。
如果我从不使用.data()
jQuery 怎么办?这能让我安全吗?
可悲的是没有。jQuery 使用相同的.data()
机制来存储其他数据,例如事件处理程序。因此,即使您从未调用将.data()
某些自定义数据与元素相关联,您仍然可能会因上述示例而导致内存泄漏。
大多数时候您可能不会注意到泄漏,但根据代码的性质,它们最终会变得大到足以成为问题。
根据jQuery 文档:
在 Internet Explorer 9 之前的版本中,如果不删除属性(使用 .removeProp( )) 在从文档中删除 DOM 元素之前。要安全地在 DOM 对象上设置值而不发生内存泄漏,请使用 .data()。