【问题标题】:Why .data() function of jQuery is better to prevent memory leaks?为什么 jQuery 的 .data() 函数更能防止内存泄漏?
【发布时间】:2010-04-30 12:09:48
【问题描述】:

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

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

为什么要使用:

document.body.foo = 52; 

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

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

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

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

谢谢,

布拉克·奥兹多安

【问题讨论】:

  • 可以stackoverflow.com/questions/1056098/…回答你的问题吗?
  • 我猜?十年来,IE 遭受了这种邪恶的折磨。但是 AFAIK 仅在您删除/分离 DOM 元素时才会发生,而它仍然设置了事件处理程序。
  • @jweyrich:虽然 IE 因内存泄漏而臭名昭著,但其他浏览器也无法幸免。
  • @Andy 非常真实!但我无法抗拒,对不起。

标签: javascript jquery memory-leaks expando


【解决方案1】:

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

假设您有变量nodeOne 和nodeTwo,它们引用节点。

假设你然后把它放在一个函数中(你不存储它的引用):

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

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

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

但是,如果您要执行相同的操作但不使用 jQuery.data,则即使不再需要这些变量,nodeOne 和 nodeTwo 变量也不会被垃圾回收.

--

我是否应该总是更喜欢 .data() 在任何情况下都使用expandos?

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

【讨论】:

  • 等等,你的代码示例是说 jQuery 的 .data() 允许还是不允许 nodeOne 和 nodeTwo 收集垃圾?
【解决方案2】:

我很确定你不能用52 这样的原始值引入内存泄漏。当应用的值包含一个引用回该元素的对象时,通常会发生使用 expandos 的内存泄漏。

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

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


刚刚意识到我没有回答你的问题哈哈。 jQuery 的 data() 提供了一个类似下面的方法:
  1. jQuery 计算数据的唯一 ID
  2. 数据存储在data() 方法可用的对象中,使用唯一ID
  3. 将 expando 属性应用于具有唯一 ID 作为原始值的元素

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

【讨论】:

  • 感谢 Andy E 的负责人(这看起来像是 Futurama 的东西!:))您提供的信息非常有用。
  • @burak:我是 Futurama 的忠实粉丝 :-)
【解决方案3】:

关于该主题的一些精彩阅读:

Memory leak patterns in JavaScript

【讨论】:

    猜你喜欢
    • 2010-09-21
    • 2015-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-10
    • 2011-12-05
    相关资源
    最近更新 更多