A few days ago, I was skimming through the MDN Web Docs when I noticed an array method I hadn't seen before: the at() method. It's experimental at the moment with literally no browser support at the time of writing, but I'll show you how you can create a helper function instead.

I really like this method. Like the eq() and get() methods in jQuery, it allows you to count backwards from the end of the array by passing in a negative index.

Non-negative indices

Let's look at non-negative indices first. This is nothing special; it works just like plain old bracket notation:

const names = ['Martin', 'Lydia', 'Ezra', 'Abigail', 'Gemma'];

names.at(0); // 'Martin' -- same as names[0]
names.at(1); // 'Lydia' -- same as names[1]
names.at(2); // 'Ezra' -- same as names[2]
names.at(3); // 'Abigail' -- same as names[3]
names.at(4); // 'Gemma' -- same as names[4]

Negative indices

The at() method shines when you want to count backwards from the end of an array. For example, to get the last item in an array using bracket notation, you have to do the following:

names[names.length - 1]; // 'Gemma'

This is fine, but it can feel a little cumbersome if you find yourself needing to do it often. It's a lot simpler with the at() method:

const names = ['Martin', 'Lydia', 'Ezra', 'Abigail', 'Gemma'];

names.at(-1); // 'Gemma' -- same as names[names.length - 1]
names.at(-2); // 'Abigail' -- same as names[names.length - 2]
names.at(-3); // 'Ezra' -- same as names[names.length - 3]
names.at(-4); // 'Lydia' -- same as names[names.length - 4]
names.at(-5); // 'Martin' -- same as names[names.length - 5]

Helper function

I promised you a helper function, so here it is:

/**
* Return the item at the given index in the array, allowing for positive and
* negative integers. Negative integers count back from the last item
* in the array.
*
* {@link https://gist.github.com/kieranbarker/1bb4ae463f3cd8138b4805983de49f4d}
*
* @param {Array} array The array
* @param {Number} index The index
* @returns {*} The item at the given index
*/

function array_at(array, index) {
if (!Array.isArray(array)) {
throw new TypeError('Expected first argument to be an array.');
}

if (typeof index !== 'number') {
throw new TypeError('Expected second argument to be a number.');
}

return index >= 0 ? array[index] : array[array.length + index];
}

You pass in the array as the first argument and the index as the second argument. If either of the arguments isn't of the expected type, the function throws a TypeError. If the given index can't be found, the function returns undefined.

Revisiting the previous examples, you'd use the function like so:

const names = ['Martin', 'Lydia', 'Ezra', 'Abigail', 'Gemma'];

// Non-negative indices
array_at(names, 0); // 'Martin'
array_at(names, 1); // 'Lydia'
array_at(names, 2); // 'Ezra'
array_at(names, 3); // 'Abigail'
array_at(names, 4); // 'Gemma'

// Negative indices
array_at(names, -1); // 'Gemma'
array_at(names, -2); // 'Abigail'
array_at(names, -3); // 'Ezra'
array_at(names, -4); // 'Lydia'
array_at(names, -5); // 'Martin'

I've made this function available under the MIT license, so feel free to use it in your own projects if you find it helpful!

A quick note

A quick note for the more eagle-eyed readers: you may be wondering why, in the last line of the function, we use the + operator instead of the - operator:

array[array.length + index];

The answer is that this bit of code only runs when index is negative. We're adding a negative number, which is the same as subtracting a positive number:

array[array.length + (-2)]; // same as array[array.length - 2]

If we were to use the - operator here, we'd be subtracting a negative number, which would cancel out and be the same as adding a positive number:

array[array.length - (-2)]; // same as array[array.length + 2]

This is not what we want.

Any questions?

Thanks for reading! If you have any feedback, feel free to shoot me an email. 😌