Turk Turk - 1 year ago 86
Javascript Question

attaching javascript objects to elements via 'data-' or directly on the element?

So I have been diving pretty deep into OOP within javascript...and oh man is it one hell of a confusing place. However, now that I can see the light at the end of the tunnel I am starting to question the practices I have learned in favor of being more concise in my code. I have this plugin running as my 'testing ground'

;(function($, window, document, undefined) {
"use strict";

$.fn.myPlugin = function(opts) {

var options = $.extend({}, { color : 'blue', normal : 'black' }, opts);

return this.each(function(id, elem) {

if (!elem.parent) // Base parent object
elem.parent = Object.create({
settings : options,
show : function (that) { $(that).css( "color", this.settings.color ); },
noShow : function (that) { $(that).css( "color", this.settings.normal); },
log : function (that) { console.log(that ? that : this); }

$(elem).children('span').each(function(idx, elmx) {

if (!elmx.child) // Child obj w/ delegation from parent
elmx.child = Object.create(elem.parent);

function() {
}, function() {
}(jQuery, window, document));

So this all works, link, but I am attaching all my objects in such a way that goes against what I have seen most people do both at work and online. Where I have my objects being attached on
, most people would do
$.data(elem, 'parent', OBJECT)
$.data(elmx, 'child', OBJECT)
. I feel my approach is more concise and isn't cluttering up the namespace. Is there any reason I shouldn't do it the way I have it, or is it really just coders preference in this situation?

For those wanting to question my two object approach to this, I just want to note this plugin exists solely for me to look at how prototypical inheritance works.

Answer Source

The reason you should use $.data instead, is because you avoid memory leaks and you don't clutter up the elements.

jQuery's $.data uses an internal map to store that data, and just a number given to every element to access it, so it's not really directly associated with the elements at all, and does not hinder garbage collection when elements are removed etc.

When you use $.data(elmx, 'child', OBJECT) the following happens

  • The element gets an unique number if it doesn’t have one, jQuery does.
    elmx[ jQuery.expando ] = id = ++jQuery.uuid
    jQuery.expando is a built in random key, to avoid conflicts across the map.

  • The data is then stored in a special object named jQuery.cache
    jQuery.cache[id]['child'] = OBJECT

  • When the data is read back from an element, the elements unique number is retrieved with
    id = elem[ jQuery.expando ]

  • The data is then read from jQuery.cache[id], not from the element.

The purpose of this is that a DOM element never references JavaScript objects directly.
Instad all data is stored in an object, using numbers as keys, so as to not be safe for memory leaks and unintended setting of properties on elements.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download