将数据存储到DOM -元素值vs数据属性

Storing data to DOM - Element value vs data attribute

本文关键字:元素 vs 数据属性 DOM 数据 存储      更新时间:2023-09-26

要在DOM元素中存储值,我们可以通过data属性

来实现。

$("#abc").data("item", 1), to retrieve do $("#abc").data("item")

但是今天我知道我们也可以这样做:

$("#abc")[0].item = 1,检索做$("#abc)[0].item

它们之间的区别是什么?哪个更好?哪一个的兼容性更广?

.data()的存在有几个原因:

  1. 一些(大多是旧的)浏览器有内存泄漏问题,如果你把一个JS对象到一个DOM对象的属性。这在DOM和JS世界(它们有单独的垃圾收集器)之间创建了一个引用,从而导致问题并可能导致内存泄漏。通过使用.data()而不是DOM属性,将引用完全保留在JS世界中解决了这个问题。老实说,我不知道这在现代浏览器中仍然是一个多大的问题。很难测试,更容易使用已知的安全方法。

  2. 历史上,一些主机对象不支持使用直接属性语法(如obj.prop = 1;)任意添加属性。.data()使得你可以将数据与任何对象相关联,而不管它是否具有处理任意属性的能力。

  3. 名称冲突。.data()在DOM对象上创建一个且只有一个自定义属性,该属性只是一个id值(字符串)。然后,您可以自由地对.data()使用您想要的任何键,而不必担心与DOM对象上已有的属性名称冲突。.data()本质上是它自己的自定义属性的名称空间。

  4. 读取HTML5 "data-xxx"属性。当您读取尚未写入实际jQuery数据存储的.data("xxx")属性时,jQuery将读取DOM对象上的"data-xxx"属性。如果它找到该属性,它返回该值并强制其类型,以便"false"转换为Javascript false。如果你写了.data("xxx", "foo"),这个值不会被覆盖到DOM对象上,而是被写入到jQuery存储中,从那时起,所有的读写都来自jQuery .data()存储。这很有用的一个原因是自定义属性(与自定义属性不同)只能是字符串,但.data("xxx", yyy)可以写入和存储任何JS数据类型。

所以,如果你想使用一个已知安全的方法,即使在旧的浏览器中也不容易出现内存泄漏,使用.data()而不是在DOM对象上创建自己的自定义属性。

我怀疑在未来的某个时候,浏览器可能会被认为足够安全,你可以将JS对象引用存储在自定义DOM属性中,而不必担心内存泄漏,到那时,使用.data()这样的东西的理由可能会减少——尽管上面的问题#3仍然存在。


使用.data()有一些缺点。

  1. 如果你在.data()中存储了大量的数据,然后你删除了相应的DOM对象,而没有使用jQuery的方法来删除它(比如你直接使用.removeChild()或者你只是在父节点上设置了.innerHTML),存储在.data()存储中的数据将成为孤儿,永远不会清理,因为jQuery不会知道相应的DOM对象已经被删除了。这将导致javascript中的一些数据保存在您永远不会使用的数据结构中。虽然从技术上讲这不是泄漏(因为数据仍然存在),但它具有浪费一些内存的相同效果。如果您使用.data(),您应该只使用jQuery方法来删除或替换DOM对象,因为它们可以防止浪费内存。

  2. 因为上面的问题,当你使用jQuery的方法,可以导致DOM对象的删除,jQuery必须做额外的工作,以确保.data()被清理时使用自己的方法。这可能会降低.html("xxx"), .remove()等的性能。