Tuesday, February 12, 2013

jQuery Object Quacks like an Array Duck

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 the typeof 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.

No comments:

Post a Comment