使用jQuery的数据存储区与expando属性

我正在使用jQuery开发代码,需要存储与某些DOM元素相关的数据。 关于如何使用html元素存储任意数据还有很多其他问题,但我更感兴趣的是为什么我会选择一个选项而不是另一个。

假设为了极其简化的参数,我想存储一个“lineNumber”属性,其中每一行都是“有趣”的表。

选项1只是在每个DOM元素上设置一个expando属性(我希望我正确使用术语’expando’):

$('.interesting-line').each(function(i) { this.lineNumber = i; }); 

选项2是使用jQuery的data()函数将属性与元素相关联:

 $('.interesting-line').each(function(i) { $(this).data('lineNumber', i); }); 

忽略我的示例代码的任何其他缺点,是否有充分的理由为什么您选择一种方法来存储属性而不是另一种?

如果您正在创作插件,则应使用$.data 。 如果您需要经常存储属性而很少需要查询DOM,那么请使用$.data

说过我所有的客户端应用程序,我倾向于在DOM元素本身上存储自定义DOM属性,以便稍后我可以使用属性[]选择器查询它们:

 var domElement = $('.interesting-line[lineNumber=' + lineNumber + ']').get(0); 

这比在每个项目上迭代包装集调用.data()更具可读性。 我经常与另一个在DOM元素上运行的第三方库进行交互,因此通过这种机制可以快速方便地访问DOM元素,从而保持代码的可读性。

它就像存储查找表将lineNumbers映射到元素一样简单,但是expando属性技术相比之下更不容易泄漏内存,因为您不存储稍后需要清理的DOM元素的引用。

5年后更新在收到[当之无愧的] downvote之后阅读本文:请忽略上面的标记文本。 jQuery不会根据expando属性集查询DOM,并且暂时还没有这样做。 所以使用$.data 。 当没有实用的方法时,没有理由污染DOM。

使用$.data可以保护您免受内存泄漏的影响。

在IE中,当您将javascript对象分配给DOM元素上的expando属性时,跨该链接的循环不会被垃圾回收。 如果您的javascript对象包含对dom对象的引用,则整个循环将泄漏。 由于闭包,完全有可能最终得到对DOM对象的隐藏引用,因此您可能会在没有意识到的情况下泄漏。

设置jQuery数据存储区以防止形成这些循环。 如果使用它,就不会以这种方式泄漏内存。 您的示例不会泄漏,因为您在DOM元素上放置了原语(字符串)。 但是如果你在那里放置一个更复杂的物体,你就有泄漏的风险。

使用$.data所以你不必担心。

使用$.data不会修改DOM。 你应该使用$.data 。 如果您正在创建一个插件,那么您应该在$.data存储一个对象,该对象具有该对象的属性,而不是将每个属性存储为$.data结构中的不同键/值对。