7

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

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

为什么要使用:

document.body.foo = 52; 

可能导致内存泄漏 - 或在什么情况下 - 所以我应该使用

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

在任何情况下,我应该总是更喜欢 .data() 而不是使用 expandos 吗?

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

谢谢,

布拉克·奥兹多安

4

3 回答 3

7

正是因为它在您给出的引文中所说的更好:“避免循环引用。”

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

假设您然后将其放入一个函数中(您不存储其引用):

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

函数运行后,有一个循环引用:nodeOne 有一个对 nodeTwo 的引用,反之亦然。

通过使用 jQuery.data,该循环引用不会阻止这两个变量被垃圾收集。

但是,如果您要执行相同的操作但使用 jQuery.data,即使不再需要变量,也不会对nodeOneand变量进行垃圾回收。nodeTwo

--

在任何情况下,我应该总是更喜欢 .data() 而不是使用 expandos 吗?

除非您正在进行大量数据设置并且需要任何额外的性能下降(并且您可以通过使用分析来判断)并且确定您不会创建循环引用(或至少是一个重要的数字),否则是的,你也可以只使用 jQuery.data。

于 2010-04-30T12:23:54.570 回答
5

我很确定您不能引入具有原始值的内存泄漏,例如52. 当应用的值包含一个引用回元素的对象时,通常会发生使用 expandos 的内存泄漏。

我建议阅读http://msdn.microsoft.com/en-us/library/Bb250448上的循环参考标题的内容。更好的是,全部阅读:-)

话虽如此,我认为大多数人建议尽可能不要使用 expandos(通常是可能的)。data()无论如何, 使用 jQuery是一个不错的选择。


刚刚意识到我没有回答你的问题,哈哈。jQuerydata()提供了一个类似下面的方法:

  1. jQuery 计算数据的唯一 ID
  2. 数据存储在data()方法可用的对象中,使用唯一 ID
  3. 将 expando 属性应用于具有唯一 ID 作为原始值的元素

每当您调用data()获取数据时,jQuery 都会访问唯一 ID 的 expando 属性并使用该 ID 从缓存对象中获取数据。因为 expando 包含一个原始值并且没有附加到缓存对象,所以不会发生循环引用。

于 2010-04-30T12:20:44.327 回答
3

关于这个主题的一些很好的阅读:

JavaScript 中的内存泄漏模式

于 2010-04-30T12:24:55.770 回答