要在DOM元素中存储值,我们可以通过data
属性
$("#abc").data("item", 1)
,检索执行$("#abc").data("item")
但今天我了解到我们也可以这样做:
$("#abc")[0].item = 1
,要检索执行$("#abc)[0].item
它们之间有什么区别? 哪一个更好?哪一个获得更广泛的兼容性?
答案 0 :(得分:17)
.data()
存在有几个原因:
如果将JS对象放入DOM对象的属性中,某些(大多数是较旧的)浏览器会出现内存泄漏问题。这在DOM和JS世界(具有单独的垃圾收集器)之间创建了一个引用,这引起了问题并可能导致内存泄漏。通过使用.data()
而不是解决该问题的DOM属性来完全保留JS世界中的引用。我真的不知道现代浏览器中存在多少问题。很难测试,更容易使用已知的安全方法。
从历史上看,某些宿主对象不支持使用直接属性语法添加任意属性,例如obj.prop = 1;
。 .data()
使得它可以将数据与任何对象相关联,无论它是否具有处理任何属性的能力。
名称冲突。 .data()
在DOM对象上创建一个且只有一个自定义属性,它只是一个id值(一个字符串)。然后,您可以随意使用.data()
所需的任何键,而无需担心与DOM对象上的预先存在的属性名称冲突。 .data()
本质上是自定义属性的名称空间。
阅读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对象上创建自己的自定义属性。
我怀疑将来可能会认为浏览器足够安全,您可以在自定义DOM属性中存储JS对象引用,而不必担心内存泄漏,此时可能会有更少的原因使用像.data()
这样的东西 - 尽管上面的问题#3仍然存在。
使用.data()
有一些缺点。
如果您在.data()
中存储有意义的数据量,然后删除相应的DOM对象而不使用jQuery的方法将其删除(例如直接使用.removeChild()
或您只需在父项上设置.innerHTML
,存储在.data()
存储中的数据将被孤立并且永远不会被清除,因为jQuery不会知道相应的DOM对象已被删除。这将导致您的javascript中的某些数据保留在您不会使用的数据结构中。虽然这在技术上不是泄漏(因为数据仍在使用中),但它与浪费一些内存的效果大致相同。如果使用.data()
,则只应使用jQuery方法来删除或替换DOM对象,因为它们可以防止浪费内存。
由于上述问题,当您使用可能导致删除DOM对象的jQuery方法时,jQuery必须做额外的工作以确保在清除.data()
时使用自己的方法。这可能会降低.html("xxx")
,.remove()
等的效果......