Javascript 什么';向DOM元素对象添加属性有什么问题?

Javascript 什么';向DOM元素对象添加属性有什么问题?,javascript,dom,object,Javascript,Dom,Object,我一直在寻找一个直截了当的答案(我能想到很多可能性,但我想知道真正的原因): jQuery提供了一个.data()方法,用于将数据与DOM元素对象关联。这有什么必要?直接向DOM元素对象添加属性(或方法)是否有问题?它是什么?我认为你可以添加你想要的所有属性,只要你只需要自己使用它们,并且属性不是方法或包含方法的对象。问题是,这些方法可能会在浏览器中造成内存泄漏。特别是在使用这种方法时,浏览器可能无法完成垃圾清理,从而导致分散的内存被占用 很好地解释了这一点 您将看到几种常见内存泄漏模式的描述,

我一直在寻找一个直截了当的答案(我能想到很多可能性,但我想知道真正的原因):


jQuery提供了一个.data()方法,用于将数据与DOM元素对象关联。这有什么必要?直接向DOM元素对象添加属性(或方法)是否有问题?它是什么?

我认为你可以添加你想要的所有属性,只要你只需要自己使用它们,并且属性不是方法或包含方法的对象。问题是,这些方法可能会在浏览器中造成内存泄漏。特别是在使用这种方法时,浏览器可能无法完成垃圾清理,从而导致分散的内存被占用

很好地解释了这一点


您将看到几种常见内存泄漏模式的描述,这与IE中的DOM不是由JScript管理的事实有关,这使得访问环境完全不同。这会导致内存泄漏。另一个原因是,当人们使用innerHTML复制节点时,所有添加的属性都不会被传输

直接向DOM元素对象添加属性(或方法)是否有问题

可能

没有web标准规定可以向DOM节点添加任意属性。它们是具有特定于浏览器的实现的“主机对象”,而不是“本机JavaScript对象”,根据ECMA-262,您可以用它们做您喜欢的事情。其他主机对象不允许您添加任意属性

事实上,由于最早的浏览器确实允许您这样做,这是一个事实上的标准,您无论如何都可以。。。除非您通过设置
document.expando=false来故意告诉IE不允许它。您自己可能不会这样做,但如果您正在编写一个脚本部署到其他地方,它可能会影响您

任意属性存在一个实际问题,即您不知道您选择的任意名称在某些尚未测试的浏览器中,或在尚未存在的浏览器或标准的未来版本中没有存在的含义。添加一个属性
元素。香肠=true
,您无法确定在空间和时间的任何地方都不会有浏览器将其用作启用浏览器崩溃功能的信号。因此,如果确实添加了任意属性,请确保为其指定一个不太可能的名称,例如
元素。这还有助于防止命名空间与可能添加任意属性的其他脚本组件发生冲突

IE中还有一个问题,您添加的属性被错误地视为属性。如果使用
innerHTML
序列化元素,您将在输出中获得一个意外的属性,例如
。如果随后将该HTML字符串分配给另一个元素,则新元素中会出现一个属性,这可能会混淆脚本


(请注意,这种情况只发生在值为简单类型的属性上;对象、数组和函数不会在序列化HTML中显示。我希望jQuery知道这一点,因为它实现
数据
方法的方法非常糟糕,会导致错误,并减慢许多简单的DOM操作。)

+1,尽管我希望你提到HTML5
data-*
storage()。对于jQuery,
数据
存储被实现为一个expando属性,该属性存储一个映射到
jQuery.cache
中的键的数值。其原理是,
jQuery.cache
可以在卸载时由浏览器自由回收,因为它不附加到任何DOM元素,相反,DOM元素可以自由回收,因为它本身不存储任何自引用对象/函数/etc。我看不出有什么问题吗?问题是(1)在对HTML执行任何操作(例如
HTML()
clone()
)时,jQuery必须从HTML中删除
jQuery(number)
属性。它通过(uuuurrrrgghhh)将字符串插入正则表达式来实现这一点。因此,如果克隆包含文本
jQuery0=“foo”
的段落,文本将消失。(2) 现在,它必须跟踪ID,而应该快速简单的DOM操作却不是。例如,尝试
remove()。哦,天哪。@bobince:re(1):真恶心。re(2):是的,jQuery在删除节点时必须删除它存储的关联数据(并且对所有子节点都这样做)。但是,如果实现将数据作为对象直接从节点存储(例如
delete node.customDataObject
+下降到所有子体),则必须执行相同的操作。也就是说,如果一个实现想要做正确的事情,那么wrt to memory.True,但是如果您将大多数JS对象连接到DOM节点,那么它们不会泄漏内存。内存泄漏的主要时间是在IE中,当对象是一个通过循环引用返回到节点的函数时(在IE7之前,在IE6中具有更糟糕的长期影响)。jQuery试图消除浏览器缺陷,但最终却给每个人带来了最低的公约数性能。(根据问题1462649判断,在这个过程中添加了它自己较小的内存泄漏。)理想情况下,“缓存”解决方案应该只用于坏浏览器,甚至可以将属性存储为结构化对象(例如,
节点。\u jquery\u id=[1]
)因此,它从未出现在
innerHTML
中,这比当前使用正则表达式的可怕业务要好。