We are unfortunately overloading a lot of meanings onto the word "data" here based on different standards and conventions. Originally it was just the "data" representing jQuery's data-binding feature but we have asymmetrically extended it to include the "data" representing the
data- attributes on an element.
.hasData() exists is to provide a way for jQuery internals to determine if a jQuery data object (i.e., an entry in
jQuery.cache) exists for a DOM element *without actually creating one*. That cannot be done with
jQuery.data() because that method is documented to return a newly created and attached data object if none previously existed.
For performance reasons, we only grab the
data- attributes once, the first time that
jQuery.fn.data is called to read an attribute that is not defined, or when it is first called to read the entire data object (see #8909). (Note that
jQuery.data doesn't pull in
data- attributes, but *will* read the cached values once they are cached.) If you ask for
data- attributes after that, you're using cached values and not the actual attribute values off the markup.
If you need to answer the question "Tell me if any
data- attributes are on this element at all -- I haven't got any idea of their possible names", and you want to know the *current* state as opposed to the jQuery-cached-data state of those values, you'll need to do what
jQuery.fn.data does -- enumerate *all* attributes, looking for ones starting
data-. That could be expensive.
Can anyone come up with a common need for something like this? Since the internal
jQuery.cache entry that
jQuery.data() reads won't necessarily match up with the real-time
data- attributes I think it might do more harm than good to provide it.
And yes, I think we've made a mess of this.