Array-like Objects in JavaScript
It may look like an Array. Hell, it even has a length attribute! However, it may not actually be an Array. JavaScript is sometimes a quirky language to say the least and the notion of what is an Array is no exception.
So what are these array-like objects that I speak of? Well there are a few of them, one of which is arguments
. arguments
is a special variable that is available inside the body of every function. It is in fact, the list of arguments that were passed in.
arguments
If you inspect the arguments
variable in a tool such as Firebug, you will notice that it prints out like an array. It has elements in sequential order and it even has a length
property.
1var testFunction = function() {
2 console.log(arguments);
3 console.log(arguments.length);
4};
So what am I griping about? Try doing arguments.shift()
. Uh-oh, looks like arguments.shift isn't a function; but that's a function of an Array. Another bit of fun you can do is console.log(arguments.constructor)
. That will print to your console "Object()" while if you did [].constructor
, that will print "Array()". Having fun yet?
This also isn't just limited to arguments
. It seems that a lot of the DOM collections are returned as these objects rather than arrays: document.getElementsByTagName()
, document.images
, document.childNodes
. In some cases, these array-not-arrays would be better suited to become arrays.
Making the Array-like Objects become Arrays
Well, that heading is a misnomer. If we want those array-like objects to behave like arrays, we are going to need a new array.
1var testFunction = function() {
2 // Create a new array from the contents of arguments
3 var args = Array.prototype.slice.call(arguments);
4
5 var a = args.shift();
6 console.log("The first argument is: %s", a);
7
8 // send the remaining arguments to some other function
9 someOtherFunction(args);
10};
Clearly, the magic is all in Array.prototype.slice.call(arguments)
. So let me break it down per piece.
Tada! As a side note, if you are used to using the prototype framework, then you can convert these array-like objects to arrays using $A()
, even though Prototype does it's array conversion differently.
Speaking of $A
. Let's say you don't like typing that long string code above and you're not using Prototype. Then you can create a shortcut just like the Prototype folks:
1var $A = function(obj) {
2 return Array.prototype.slice.call(obj);
3};
4
5// Example usage:
6$A(document.getElementsByTagName("li"));
Comments
comments powered by Disqus