1

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);

                $(elmx).hover(
                    function() {
                        elmx.child.log();
                        elmx.child.show(elmx);
                    }, function() {
                        elmx.child.noShow(elmx);
                    });
            });
        });
    };
}(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 elem.parent.OBJECT and elmx.child.OBJECT, most people would do $.data(elem, 'parent', OBJECT) and $.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.

4
  • 1
    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. Commented Oct 6, 2016 at 16:32
  • 1
    @adeno That sounds like an answer not a comment. Very similar to what I was going to post as an answer. Commented Oct 6, 2016 at 16:34
  • 1
    Well, I've already written it, so why not? Commented Oct 6, 2016 at 16:34
  • 1
    @adeno That's better, now I can upvote it! Commented Oct 6, 2016 at 16:36

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

To add to this, see the jQuery documentation: api.jquery.com/data. In jQuery3 there are additional benefits to using $.data.
Thank you, I had no idea that was a concern

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.