jQuery Array-like Object
I'm sure you've heard of the old saying, "If it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck".
Well, a simular statement could be said about the
jQuery Object
. If the jQuery Object
looks like an array, indexes like an array, console.logs like an array, then it probably is an array... err, well, but in this case it's NOT an array!Let's unpack this a little more and see what sense we can make out of it. The following snippet of code invokes the
jQuery Function
and performs a selection from the DOM and then accesses the returned jQuery Object
to locate the DOM element at index 2, which feels an awful lot like an array.Upon further examination in the console the
jQuery Object
is indeed an object
(not an array) as indicated by the $.type()
utility method.Note: You might notice that I am using the lesser known$.type()
utility method to determine the type of the variable. I am not using thetypeof
operator because it evaluates to "object" for both arrays and objects. The$.type()
method returns much more useful data http://api.jquery.com/jquery.type/
Something of interest in the above screenshot is the grayed out
__proto__
property. That is where all the jQuery goodness (functionality) can be found such as .fadeOut()
, .on()
, .addClass()
, and all the other methods jQuery provides.After some digging in the jQuery source code I came across the following
merge
method where the array results of the DOM selection gets copied over to the jQuery Object
. In addition to mapping over these values jQuery also provides a .length
property and a .splice()
method which enables itself to mimic an array.Making a Custom Array-like Object
So, what about making our own custom array-like object!?! The following small snippet of JavaScript defines an object and then assigns a set of key/value pairs. In order to mimic an array we need to add a
.length
property and expose a .splice()
method borrowed from the array. The following is a screenshot of what is console.logged after executing the above code snippet. You will see that our
array_like
object is treated as if it were an array just the like jQuery Object
... yay!Note: If we take off the.length
property or the.splice()
method then the custom object will no longer appear as an array in the console. They are both necessary.
Conclusion
So, inductive reasoning might be a good thing most of the time, but in this case the Duck Test failed us. You can play around with the code snippets above by looking at the following JSFiddle.