I am Hack Sparrow
Captain of the Internets.

JavaScript Array-like Objects

Have you heard about array-like objects in JavaScript? If no, this is a good post to learn about them. Array-like objects are not a separate object type, they are the same old object we are familiar with, except they 'look' like arrays. What do I mean by that? Let's find out.

You might be familiar with the arguments variable which every JavaScript function has access to by default. We access its items using arguments[0], arguments[1] etc. Let's take a look how it works.

function test() {
console.log('Total Arguments: ' + arguments.length); //2
console.log('First Argument: ' + arguments[0]); // A
console.log('Second Argument: ' + arguments[1]); // B
arguments[2] = 'C';
console.log('Third Argument: ' + arguments[2]); // C

test('A', 'B');

That looks an array. Only it isn't really an array! If it indeed is an array, we should be able to push stuff to it. Let's give it a try.

// TypeError: Object has no method 'push'

You will soon realize that none of the array methods, like pop(), shift(), forEach() etc work.

So, how do we explain its array-like behavior?

Well, in our example above, the object looks like this: {"0": "A", "1": "B"}. What we thought were array indexes were actually object keys. Now that you know the object structure, it is obvious why arguments[0] and arguments[2] = 'C' worked flawlessly.

What about arguments.length? That looks like an array's property.

Here is an eye-opener, the actual structure of the object looks like this: {"0": "A", "1": "B", "length":2}. Yes, it comes with a hidden (non-enumerable) property called length. Infact, the arguments object contains two other hidden keys - caller and callee (some environments may not contain caller). Here is the proof:

function test() {
// [ '0', '1', 'length', 'callee' ]
test('A', 'B');

Object.getOwnPropertyNames() returns an array containing the names of all of the given object's own enumerable and non-enumerable properties.

So here is what an array-like object is: an object with numerically incrementing keys starting from 0, with a property named length which is the count of the number of numerical keys.

Are there any other examples of array-like objects which are 'native' to a JavaScript environment? There are many, for example: document.getElementsByTagName(), document.getElementsById() etc. Here is an example again:

var d = document.getElementsByTagName('div');
var new_div = document.createElement('div');
d.push(new_div); // Error

There will be situations when you'd want to convert an array-like object to a real array (most probably the arguments object).

We can't call slice() on arguments because it doesn't have that method, but using JavaScript's call() method we can attach Array.prototype.slice() to any object with a numerically incrementing key, and a length key, and execute the slice() method on the object.

Here is an example of doing that:

var array = Array.prototype.slice.call(arguments);
array.push('Hey!'); // success

So that's it about array-like objects in JavaScript. This post might have made you curious about call(). You can learn more about call() and its related apply() method in this post.

Make a Comment