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:
The jQuery selector code returns an array by itself. No need to do anything with it.
When a jQuery object is passed to the $() function, a clone of the object is created. This new jQuery object references the same DOM elements as the initial one.
Summary. JavaScript doesn't support functions that return multiple values. However, you can wrap multiple values into an array or an object and return the array or the object. Use destructuring assignment syntax to unpack values from the array, or properties from objects.
The $. each() function can be used to iterate over any collection, whether it is an object or an array. In the case of an array, the callback is passed an array index and a corresponding array value each time.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With