DEV Community

Cover image for Stop using Array[index], use Array.at() instead
Timotius Sitorus
Timotius Sitorus

Posted on

Stop using Array[index], use Array.at() instead

Array.at() is a brand new Javascript array method that solves a lot of common issues with the standard Array[index] method of accessing elements in an array. With it, we finally have the ability to do Negative Indexing natively in Javascript.

Negative Indexing

Negative Indexing is the ability to use negative numbers as index to access elements in arrays from the end rather than the start. For example if you want the last element in an array named arr, you would want to do arr[-1]. Sadly, this doesn't behave the way we want it to in Javascript because the [] syntax does not belong to arrays and string, but rather to all objects.

The [] syntax with objects means getting the property of an object with that key. Since arrays and strings are object, this applies to them as well. Under the hood, arrays and strings assign each element to a key that matches with its current index.

// When it comes to indexing, 'arr' behaves exactly like 'obj'
const arr = ['cat', 'dog', 'fish', 'bird'];

const obj = {
   0: 'cat',
   1: 'dog',
   2: 'fish',
   3: 'bird'
};
Enter fullscreen mode Exit fullscreen mode

So arr[-1] already is valid Javascript, but instead of returning the last element, it tries to return the value of the "-1" key of the array, which is usually undefined.

Existing Workarounds

Currently, there are a few ways of getting this behavior to work correctly. The first is to subtract the negative index from the length of the array.

const pets = ['cat', 'dog', 'fish', 'bird'];
const lastPet = pets[pets.length - 1];

console.log(lastPet); // Prints out 'bird'
Enter fullscreen mode Exit fullscreen mode

This works and is the way that most developers get around this limitation, but there are a few issues:

  • The name of the array is called twice and it's generally pretty lengthy.
  • This can't be used for values that have not been assigned to a variable.
  • This can't be used to get the last item of the return value of a function unless it's first store it in a temporary variable.
['cat', 'dog', 'fish', 'bird'][ **what do you put here** - 1];

const a = () => ['cat', 'dog', 'fish', 'bird']; 
a()[ **What do you out here** - 1];
Enter fullscreen mode Exit fullscreen mode

The other method is to use Array.slice() which has negative indexing built in.

const pets = ['cat', 'dog', 'fish', 'bird'];
const lastPet = pets.slice(-1)[0];

console.log(lastPet); // Prints out 'bird'
Enter fullscreen mode Exit fullscreen mode

This actually resolves many of the issues of the previous method, but introduces a few new ones:

  • The syntax is not immediately understandable, specifically the trailing [0] since slice returns an array.
  • A temporary array is created from the desired index to the end of the array which is immediately discarded.

Array.at()

That is why Array.at() was implemented. It works exactly how Array[index] with positive numbers, but correctly implements negative indexing for negative numbers.

const pets = ['cat', 'dog', 'fish', 'bird'];
const lastPet = pets.at(-1);

console.log(lastPet); // Prints out 'bird'
Enter fullscreen mode Exit fullscreen mode

This provides a cleaner syntax than the previous methods and doesn't suffer from any performance penalties. It is currently available in most modern browsers with Polyfills available if you need it.

If you want to learn more, check out the MDN reference for it. You can also read the original proposal for it.

Top comments (5)

Collapse
 
pengeszikra profile image
Peter Vivo

When I was used .at in complex project which developed under chrome browser and everything is work fine, but after run that program under Electron, then crashed ... because Electron JS engine is not the latest one, so this function also proper to guard against older JS engine.

Collapse
 
leob profile image
leob

Sorry, but "Stop using Array[]" and then the ONLY reason you come up with is negative indexes? Could be me, but I'm very very rarely having that use case ... you want to convince me, try again ;)

Collapse
 
colonelxy profile image
Harold Oliver 🛡️

Just agree to it's cleanness.....

Collapse
 
leob profile image
leob

Not convinced lol, sounds like a very subjective thing

Thread Thread
 
urielbitton profile image
Uriel Bitton

agreed haha