views:

412

answers:

3

Should I pair every data() call with a later removeData() call?

My assumptions: jQuery's remove() will remove elements from the DOM, and if I don't have any other references to remove, I don't have to do any more clean up.

However, if I have some javascript var or object referring to one of the elements being removed, I'll need to clean that up, and I'm assuming that applies to jQuery's data function, too, because it's referencing the elements somehow.

So if I do need to call removeData before remove, is there a shortcut to remove all data associated with an element or do I have to call each explicitly by name?

Edit: I looked through the source code and confirmed what Borgar and roosteronacid said. Remove takes the elements out of the dom and deletes any events and data stored with them - which is convenient, but makes me wonder when you would use removeData(). Probably not often.

A: 

By and large, javascript is fairly good about knowing when it's appropriate to collect the garbage, and unless you're writing very large-scale or long-running client-side apps, I'd say the memory involved is mostly inconsequential and trying to second-guess it isn't gonna gain you a lot.

Determining what unfinished lexical closures or other tricky javascript in jQuery might still be accessing your given data could be pretty complicated in some cases.

As far as I'm aware, though, if you store a reference to whatever you got with jQuery's data function then it would continue to exist after the element is removed, so removing that reference would be necessary as well. Some simple test cases would give you a more definite answer.

Gabriel Hurley
+2  A: 

The whole point of jQuery is to abstract away from crappy JavaScript implementations and bugs in browsers.. such as memory leaks :)

.. Yup; all associated data to an element will be removed when that element is removed from the DOM.

roosteronacid
+8  A: 

jQuery's data does not keep a reference to the element so that you don't need to worry about memory leaks. It's intended purpose is to solve this exact problem.

A slight simplification of how it works:

An id member is added to each "touched" DOM node. All subsequent actions involving that DOM element use that id.

var theNode = document.getElementById('examplenode');
theNode[ 'jQuery' + timestamp ] = someInternalNodeID;

You can access the id using the same function jQuery uses:

someInternalID = jQuery.data( document.body );

When you append data to the node it stores that on the jQuery object, filed under the node's internal id. Your $(element).data(key,value) translates internally to something like:

jQuery.cache[ someInternalNodeID ][ theKey ] = theValue;

Everything goes into the same structure, including event handlers:

jQuery.cache[ someInternalNodeID ][ 'events' ][ 'click' ] = theHandler;

When an element is removed, jQuery can therefore throw away all the data (and the event handlers) with one simple operation:

delete jQuery.cache[ someInternalNodeID ];

Theoretically, you may therefore also remove jQuery without leaks occurring from any references. jQuery even supports multiple separate instances of the library, each holding it's own set of data or events.

You can see John Resig explaining this stuff in the "The DOM Is a Mess" presentation.

Borgar