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

Awe*_*own 17 javascript jquery expando

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

为了极其简化的参数,我想要存储一个"lineNumber"属性,其中每一行都是"有趣"的表.

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

$('.interesting-line').each(function(i) { this.lineNumber = i; });
Run Code Online (Sandbox Code Playgroud)

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

$('.interesting-line').each(function(i) { $(this).data('lineNumber', i); });
Run Code Online (Sandbox Code Playgroud)

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

Sea*_*lan 21

使用$.data将保护您免受内存泄漏.

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

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

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


Cre*_*esh 13

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

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

var domElement = $('.interesting-line[lineNumber=' + lineNumber + ']').get(0);
Run Code Online (Sandbox Code Playgroud)

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

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

5年后更新 在收到[当之无愧的] downvote之后阅读本文:请忽略上面的标记文本.jQuery也没有查询基础上设置expando属性的DOM,并没有一会儿这样做.所以使用$.data.当没有实用的方法时,没有理由污染DOM.

  • 有一个[jQuery插件](http://plugins.jquery.com/files/jquery.dataSelector.js.txt),它允许你使用选择器,如var`domElement = $('.interesting-line:data("lineNumber) ='+ lineNumber +'")').get(0);` (2认同)