Fun with arrays

ยท

4 min read

In this article, we'll look at some weird quirks with JavaScript arrays to learn a little more about how they work under the hood.

An array is a collection or list of values. It could hold just strings:

const names = ['Luke', 'Leia', 'Han'];

Or a mix of different types:

const stuff = ['Hello', 42, true, 3.14];

Arrays are cool because you can iterate over them with a for loop or one of the array utility functions like forEach, map, or reduce.

What does length really mean?

Let's start with a normal, everyday case. If you have an array, you can check its length property to see how many items are in the array:

const values = ['one', 'two', 'three'];
console.log(values.length);

The console.log above will print 3, because there are three elements in the array.

What happens if you do this, though:

const names = [];
names[10] = 'Joe';
console.log(names.length);

There's only one name in this array, but the console.log will print 11.

Here's another one. You probably won't ever see this in real-world code, but it helps illustrate the point:

const names = [];
names[10] = 'Joe';

// You'd never do this in real life
names[12.5] = 'Bob';

console.log(names.length);

What do you think will be printed now? If you guessed 11 again, you're correct. By now you can see that the length of an array actually does not indicate the number of values in the array.

If you check the value at names[12.5], you'll see that Bob is, in fact, there:

console.log(names[12.5]); // 'Bob'

So what does length really mean?

The answer to this mystery lies in the ECMAScript Language Specification. It says:

The "length" property of an Array instance is a data property whose value is always numerically greater than the name of every configurable own property whose name is an array index.

So what constitutes an array index? In short, the specification says that it's an integer value.

That explains why, in the second example, setting names[12.5] to Bob did not affect the length property. 12.5 is not an integer value!

Array-like objects

JavaScript has a notion of array-like objects. These are objects that have properties indexed like an array, but aren't actually arrays. Array-like objects also have a length property.

Here's a contrived example of an array-like object:

const names = {
    0: 'Joe',
    1: 'Bob',
    2: 'Bill',
    length: 3 // don't forget the length!
};

You can use an array-like object in a for loop:

for (let i = 0; i < names.length; i++) {
  console.log(names[i]);
}

That's cool, but you can do more. Because this object fulfills the contract of an array-like object, you can use array methods like map with a little JavaScript trickery:

const uppercaseNames = Array.prototype.map.call(names, name => {
    name.toUpperCase());
});

In the above example, uppercaseNames will be an array (an actual array!) of the names uppercased: ['JOE', 'BOB', 'BILL'].

This isn't too useful for a weird array-like object you constructed by hand, but it can come in handy when working with the DOM.

For example, consider the document.querySelectorAll method. You might think this returns an array, but it actually returns a NodeList. This is an array-like object. It even has a forEach method, but it's missing other array methods like map or find.

You could use find on a NodeList to search for a node that meets a certain condition. Or, maybe you want to use map to transform the nodes into an array of their attribute values.

The incredible shrinking array

I'll leave you with one last array trick. Did you know that you can change an array's length property? That's right, the property is writable.

If you set the length to a smaller value, any remaining elements are removed from the array:

const names = ['Joe', 'Bob', 'Bill'];
names.length = 1;

console.log(names); // ['Joe']
console.log(names[1]); // undefined
console.log(names[2]); // undefined

Not only does this change the length of the array, but it gets rid of the extra elements, too.

Conclusion

If you've been working with JavaScript for any length of time, this array weirdness shouldn't surprise you. And if you are new to JavaScript (welcome!) consider this a sign of interesting things to come.

I hope you found this array trivia to be interesting, and maybe even a little useful!