为什么jQuery的.data()函数更好于防止内存泄漏?

7

关于jQuery实用函数jQuery.data(),在线文档中说:

“jQuery.data()方法允许我们以一种安全的方式将任何类型的数据附加到DOM元素上,避免了循环引用和内存泄漏。”

为什么要使用:

document.body.foo = 52; 

当出现内存泄露的情况时,我应该使用什么 -或在什么条件下- 来避免此类问题。

jQuery.data(document.body, 'foo', 52);

在任何情况下,我是否都应该优先使用.data()而不是使用扩展属性?

(如果您能提供一个例子来比较差异,我将不胜感激)

谢谢,

burak ozdogan


1
这个问题的答案可能在 https://dev59.com/IUjSa4cB1Zd3GeqPDTNz 上。 - Konerak
我猜可以吗?IE已经遭受了这个问题十年之久。但据我所知,只有在您删除/分离DOM元素时仍设置事件处理程序时才会发生这种情况。 - jweyrich
@jweyrich:虽然IE因内存泄漏而声名狼藉,但其他浏览器也不免其疾。 - Andy E
@Andy非常正确!但我忍不住了,抱歉。 - jweyrich
3个回答

7

正是因为引用中的“安全于循环引用”,所以它更好。

假设你有变量nodeOnenodeTwo,它们引用节点。

然后假设你将它们放入一个函数中(你不存储该函数的引用):

jQuery.data(nodeOne, 'item', nodeTwo);
jQuery.data(nodetwo, 'item', nodeOne);

函数运行后,存在一个循环引用:nodeOne 引用了 nodeTwo,反之亦然。使用 jQuery.data,这种循环引用不会阻止这两个变量被垃圾回收。然而,如果你在不使用 jQuery.data 的情况下执行相同的操作,即使这些变量不再需要,nodeOne 和 nodeTwo 变量也不会被垃圾回收。除非你需要大量数据设置并且需要任何额外的性能优化(你可以通过分析来确定),并且确定不会创建循环引用(或至少不会影响到程序),那么是的,最好只使用 jQuery.data。

等一下,你的代码示例是在说jQuery的.data()是否允许nodeOnenodeTwo被垃圾回收吗? - Crescent Fresh

5
我非常确定,像 52 这样的基本值不会导致内存泄漏。使用 expandos 时,通常是在应用包含对元素的引用的对象的值时发生内存泄漏。
我建议阅读 http://msdn.microsoft.com/en-us/library/Bb250448 中的循环引用部分内容。最好全部阅读 :-)
话虽如此,我认为大多数人建议尽可能避免使用 expandos(通常可以避免)。在任何情况下,使用 jQuery 的 data() 是一个好的选择。
刚刚意识到我没有回答你的问题 lol。jQuery 的 data() 提供了以下方法:
  1. jQuery 为数据计算一个唯一的 ID
  2. 使用唯一的 ID 将数据存储在可用于 data() 方法的对象中
  3. 将 expando 属性作为基本值应用于具有唯一 ID 的元素
每当您调用 data() 获取数据时,jQuery 访问唯一 ID 的 expando 属性,并使用该 ID 从缓存对象中获取数据。因为 expando 包含基本值并且没有附加到缓存对象,所以不会出现循环引用。

感谢安迪·E的头(这看起来像《飞出个未来》中的某些东西! :) ) 您提供了非常有用的信息。 - pencilCake
@burak:我是一位狂热的《飞出个未来》粉丝 :-) - Andy E

3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接