9

I am attempting to reproduce jQuery's (1.7.1) object structure, to better understand how it it works. I have the following code:

(function (window, undefined) {

    var document = window.document,
        navigator = window.navigator,
        location = window.location;

    window.myclass = (function () {
        var __con = function () {
            return new __con.fn.init();
        }

        __con.fn = __con.prototype = {
            'init' : function () {
                return this;
            },
            'test' : function () {
                console.log('test1');
                return this;
            }
        }

        __con.fn.init.prototype = __con.fn;

        __con.test = function () {
            console.log('test2');
            return this;
        }

        return __con;
    })();

})(window);

My console looks like this:

> myclass().test();
  test1
< __con.fn.__con.init
> myclass.test();
  test2
< function () {

            return new __con.fn.init();

        }

My confusion is how jQuery is able to return an array and still have it be a jQuery object? jQuery being executed from the console might look something like:

> $(document.body)
  [<body>​…​</body>​]
> $(document.body).css('width');
  "1263px"

In fact, one thing that I definitely noticed is the lack of < for the return object. So what exactly is going on here? I've searched all over Google to explain how jQuery works, to no avail. Maybe I'm just getting the terminology wrong, I'm not sure. It seems I can't find any detailed source explaining this.

Perhaps my code is just incomplete, but the basic structure that I have so far is what I've been able to extract so far. Please correct what I have so far if it is wrong, incomplete, or inefficient, and by all means please feel free to provide good reading about:

  • Javascript best practices
  • How jQuery works
  • Efficient Javascript classes
  • Things all about Javascript object structures
    • Singletons
    • Prototypes
    • Anything else related to whatever this type of structure is called
Charles
  • 50,943
  • 13
  • 104
  • 142
Shea
  • 1,965
  • 2
  • 18
  • 42
  • 1
    I'm not sure I understand your question entirely, but have a look at this answer I posted a while back and see if it helps: http://stackoverflow.com/questions/7651404/how-does-jquery-create-array-objects/7651455#7651455 – davin Feb 22 '12 at 08:49
  • 1
    I've found these talks to be incredibly helpful: http://yuiblog.com/crockford/ – romario333 Feb 22 '12 at 09:13
  • Not quite sure how community wikis work. I understand I will no longer be able to obtain reputation from it, and from what I can tell all you need to form one is to close the question. If that's correct, please vote to close this. Through my inability to successfully answer my own question using Google, I would like this to be the place to learn all about `jquery-internals`. Yea or nay to form a community wiki? – Shea Feb 22 '12 at 10:28
  • Maybe I don't quite get the community wiki concept yet. I may have misunderstood what I've read about it so far. – Shea Feb 22 '12 at 10:36
  • Community wiki is a tool that lets you make a post editable by users with 100+ reputation, a much lower threshold. It's designed to make posts accessible for curating to a much larger audience. One of the side effects of CW is no reputation gain or loss, but that should not be the primary motivation for using it. See [Community wiki is dead, long live community wiki!](http://blog.stackoverflow.com/2011/08/the-future-of-community-wiki/) – Tim Post Feb 22 '12 at 10:41
  • If you're interested in more information, try to formulate another question. I'm rolling back the last edit (seems like you hesitated with it a bit). Note, I'm not locking this. – Tim Post Feb 22 '12 at 10:42
  • Thanks for the explanation. The main problem I am facing with extending my knowledge on Javascript, is the lack of correct terminologies to search for. Maybe it's possible to search Google for terminologies to use for searching Google... Than again, not knowing what to search for is exactly what makes this site so useful. – Shea Feb 22 '12 at 11:00
  • @Tim Post Your link about community wikis helped me realize it's actually better this way, as smaller questions focused to a certain point along with tags. It causes the site to become _the_ community wiki as an entirety. My question is the first of the `jquery-interals` tag, but in time the questions and answers that will share this tag in the future, will form the community wiki about the jQuery object semantics... I guess I just wanted you to know I learned something new with your link. – Shea Feb 22 '12 at 11:16
  • @andrewjackson I've been leaning on SO quite heavily to get me out of some fine jQuery messes of my own creation, I completely sympathize with not knowing what to search for. Have you found our chat system yet? Lots of fine folks that can help point you to the right search term. Trust me, if you start a message with "I'm trying to figure out what keywords to search on SO", many people will trip over themselves to help you, since many people never bother searching. – Tim Post Feb 22 '12 at 11:50
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/8067/discussion-between-andrewjackson-and-tim-post) – Shea Feb 22 '12 at 12:03

1 Answers1

9

jQuery objects are array-like, so look and behave a lot like arrays, but are in fact just custom objects made to roughly equate to a collection of DOM nodes (except with added functionality). All the array-like functionality - length, slice() etc.. - is in fact added manually to the jQuery prototype (for which jQuery.fn is an alias), sometimes by calling an array function with the jQuery object as context

  slice = Array.prototype.slice,
  ...
  slice: function() {
    return this.pushStack( slice.apply( this, arguments ),
      "slice", slice.call(arguments).join(",") );
  },

and sometimes by writing it from scratch. Look at the annotated code (probably a very useful resource for you - it covers v1.6.2 but I don't think anything too drastic has changed since then, except maybe the addition of $.callbacks) to see that this.length is set manually e.g.

if ( selector === "body" && !context && document.body ) {
  this.context = document;
  this[0] = document.body;
  this.selector = selector;
  this.length = 1;
  return this;
}

the jQuery.buildFragment() method is also fundamental to how jQuery objects containing larger collections of DOM nodes are constructed.

So to sum up, jQuery doesn't use arrays, it just looks like it does because much native array functionality has been replicated as properties of the jQuery prototype.

Community
  • 1
  • 1
wheresrhys
  • 22,558
  • 19
  • 94
  • 162
  • Is it really added manually? Other frameworks I've seen (ender) just create an array and add properties to it. – beatgammit Feb 22 '12 at 21:34