为什么';JQuery是否公开其UUID功能?

为什么';JQuery是否公开其UUID功能?,jquery,uuid,expando,Jquery,Uuid,Expando,在引擎盖下面,JQuery使用一个“uuid”映射(只是它维护为JQuery.uuid)来解决浏览器在从Javascript将属性附加到DOM中的标记时存在的众所周知的内存泄漏问题。与此相反,JQuery使用$.data(标记、名称、值)将数据存储在一个映射中,该映射由uuid(一个可以通过选中标记[JQuery.expando]来确定的键)键入 虽然$.data()非常有用,但有时您希望将数据映射到标记,而不将数据转储到一个全局存储桶中—您希望自己的数据存储桶更小,例如,可以检查长度或循环 作

在引擎盖下面,JQuery使用一个“uuid”映射(只是它维护为
JQuery.uuid
)来解决浏览器在从Javascript将属性附加到DOM中的标记时存在的众所周知的内存泄漏问题。与此相反,JQuery使用
$.data(标记、名称、值)
将数据存储在一个映射中,该映射由uuid(一个可以通过选中
标记[JQuery.expando]
来确定的键)键入

虽然
$.data()
非常有用,但有时您希望将数据映射到标记,而不将数据转储到一个全局存储桶中—您希望自己的数据存储桶更小,例如,可以检查长度或循环

作为一个精心设计的示例,假设您的图标在单击时会在4种状态之一旋转。当一个图标处于状态2时,您希望将其添加到状态2的图标数组中。最明显的方法是将标签添加到数组中;但是,这样做会造成内存泄漏。您可以在复选框上调用
$.data()
,但这并不能完全完成您要做的事情-您必须循环检查所有复选框,并将
$.data()
与它们进行对比,以确定哪些在列表中,哪些不在列表中

您需要在一个数组中存储一些标记的抽象,这就是jQuery的UUID。您可以编写自己的UUID功能,但理想情况下,出于代码大小和质量原因,您只需利用JQuery内置的UUID功能即可。您可以要求JQuery通过调用
$.data(tag'unrelated',1)
隐式地将UUID附加到标记上,然后选中
标记[JQuery.expando]
,以获取其UUID,最后在列表中使用它。。。但这有点像黑客。实际上,理想的做法是在公共API中公开以下内容:

$.getUuid(标记)
:检查并创建UUID(如果不存在)-理想情况下,该方法将从
$.data()
中分解出来,并为传入的标记创建或获取UUID

那么,在jQuery中,有没有一个原因没有考虑到它自己的方法呢?这在某种程度上有害吗?难道这从来就不是什么有用的东西吗


我应该注意到,我实际上已经在我们使用的jQuery版本中考虑到了这一点,这非常有用。但也许有一个潜在的风险,我没有击中在我的使用。我也知道有一个插件可以实现这一点,但是它有点坏了——有两个代码路径来执行相同的UUID功能既有点浪费,也有点脆弱。

我认为这里的答案很明显,jQuery构建UUID是为了内部使用,而且还没有找到让它公开使用的好理由或好需求。这并不意味着理由不存在,只是它们似乎不够重要,不足以让它排在工作清单的首位

用作唯一ID的单原子递增计数器实现起来非常简单,我已经使用过很多次了。我不觉得这样做需要类库支持

我认为你对内存泄漏的恐惧是因为你把对象引用放在周围有点言过其实了。首先,如果您删除了对象并忘记删除对它的引用,那么这只是内存泄漏。这只是垃圾收集语言中的一条一般规则,您必须“知道”将对象的引用保存在何处,以便在希望释放对象时清除这些引用

第二,如果你每页做很多次同样的事情,或者对象非常非常大,那么这只是一个有意义的内存泄漏。当你进入下一个页面时,它们都会被清理干净,所以这不像是一个永远积累的东西,除非你永远不会离开浏览器页面,反复做同样的事情,包括删除对象,但引用不会被删除

第三,jQuery的.data()机制试图在使用DOM对象时为您解决很多问题

第四,在您设计的示例中,这不会造成内存泄漏,除非您在状态2中的图标数组不再有效或不再使用时不清理它。如果将其清理干净,那么在该数组中存储直接DOM引用就没有问题。如果不清理数组,那么即使数组本身存在内存泄漏,即使其中包含抽象UUID而不是DOM引用。使用抽象引用只是比大多数时候需要做的工作多得多


同样,即使您让它泄漏,泄漏也只在页面寿命较长且您重复创建和释放对象时才重要,但并没有以引用随时间累积的方式清除对它们的所有引用,并且这样做足以使它们导致的内存泄漏有意义。我一直在JS变量中保留对DOM对象的引用。我只是小心地确保在我不再需要它们时将它们清空,这样我就知道DOM对象可以在将来某个时候被释放。

这已提交给jQuery团队并被拒绝

但是,您可以维护将垃圾收集委托给jQuery的标记列表,如下所示:

基本守则如下:

sets[oldIndex] = sets[oldIndex].not(this);
sets[index] = sets[index].add(this);
尽管这会产生一个单独的内存负担—这些方法不仅仅是向数组添加标记,它们还维护此集合先前状态的堆栈(.pushStack()在内部调用)。如果页面具有大量用户操作,则集合将不受限制地增长。为了防止出现这种情况,您可以对对象进行黑客攻击以删除堆栈:

sets[oldIndex] = sets[oldIndex].not(this);
sets[oldIndex].prevObject = null;
sets[index] = sets[index].add(this);
sets[index].prevObject = null;

浪费了一些CPU周期,但足够干净。

我认为这是一个很好的问题,但通过电子邮件将其发送给jQuery维护人员可能会更有效:-)或者,记录一个错误-他们确实认真对待错误列表。我想他们必须在将该功能公开给外界之前对其进行重命名:顺序整数几乎是univ