How does jQuery .data() work?

I want to use .data() in my application. The examples are helpful, but I do not understand however where the values are stored.

I inspect the webpage with Firebug and as soon as .data() saves an object to a dom element, I do not see any change in Firebug (either HTML or Dom tabs).

I tried to look at jQuery source, but it is very advanced for my Javascript knowledge and I lost myself.

So the question is:

Where do the values stored by jQuery.data() actually go? Can I inspect/locate/list/debug them using a tool?


Solution 1:

Have a look at the source for it.

From a quick glimpse, it looks like it's storing the data in that cache variable that is created on line 2.

Edit:

Here's a quick demo that finds the data in the cache: http://jsfiddle.net/CnET9/

You can also dump $.cache to your console and explore it manually.

Solution 2:

You seem to have gotten the answer to where, but here is a bit on the how. There are some rules you should be aware of before using this.

ADDING

Adding variables using the object returned from $('.selector').data() works because the data object passes by reference, so anywhere you add a property, it gets added. If you call data() on another element, it gets changed. It is what it is what it is...

var oData = $('#id').data();
oData.num = 0;
oData.num == $('#id').data().num; // true

Adding an object places a object inside of the data object, as well as "extends the data previously stored with that element." - http://api.jquery.com/data/#entry-longdesc

That means that adding an obj to dataObj becomes

oData.obj = {};    
oData === { /*previous data*/, obj : { } }

Adding an array does not extend the data previously stored, but doesn't behave the same as a simple value either...

USING

If you have simple values stored, you can place them into variables and do what you want with them without changing the data object.

however

if you are using an object or array to store data on an element, beware!

Just because you store it to a variable does not mean you are not changing data value. Just because you pass it to a function does not mean you are not changing data values!

It is what it is what it is.. unless it's simple.. then it's just a copy. :p

var data             = $("#id").data();  // Get a reference to the data object 
data.r_redirect      = "index.php";      // Add a string value
data.num             = 0;                // Add a integer value
data.arr             = [0,1,2];          // Add an array
data.obj             = { a : "b" };      // Add an object

                                         // but here is where the fun starts! 

var r_redirectString = data.r_redirect;  // returns "index.php", as expected.. cool
r_redirectString     = "changed"         // change the value and the compare :
data.r_redirect      == r_redirectString // returns false, the values are different

var oArr             = data.arr;         // Now lets copy this array
oArr.push(3);                            // and modify it.
data.arr            == oArr              // should be false? Nope. returns true.
                                         // arrays are passed by reference.
                                         // but..

var oObj             = data.obj          // what about objects?       
oObj["key"]          = "value";          // modify the variable and
data.obj["key"]     == oObj["key"]       // it returns true, too!

So, resources..

What's the best way to store multiple values for jQuery's $.data()? https://stackoverflow.com/a/5759883/1257652

Solution 3:

You can inspect it by just calling .data() without params, like this:

$("div").data("thing", "value");​​​​​​
console.log($("div").data());
//or...
console.log($.data($("div").get(0)));

As for the "where", it's stored in a global jQuery cache object under a key that represents your element. Calling .data() really returns jQuery.data(yourDomElement), or tack on a key to that if you called for a specific value from it.