Using the new JavaScript .at() method
Tags: javascript, webdev, programming, tutorial
Published: 2021-10-18 19:18:15

**Written by [Ibadehin Mojeed](https://blog.logrocket.com/author/ibadehinmojeed/)** ✏️

The JavaScript `.at()` method was introduced in the August release of the ECMA International TC39’s relative indexing proposal to allow developers to grab elements based on their indexes.

Selecting elements in JavaScript is a common occurrence in development, but, before the introduction of the `.at()` method, JavaScript had existing methods and techniques to select elements or characters from the start or end of lists or within a string.

The bracket notation, `[]`, is commonly used to get an element at a specific index. But, this has its drawbacks. For instance, we cannot use a negative index syntax like `arr[-1]` to access the last item in a list, which has become popular in Python.

Consequently, developers resort to using the `slice()` method and the `length` property to grab items from the end of a list. Nonetheless, they also have their respective drawbacks.

In this tutorial, we’ll look at the JavaScript `.at()` method, its use cases, and how it can improve developers’ experiences compared to preexisting methods.

## The indexable object prototype

The `.at()` method is located on the [`prototype`of indexable objects](https://blog.logrocket.com/interfaces-in-typescript-what-are-they-and-how-do-we-use-them-befbc69b38b3/#indexable-properties-interfaces).

These objects, which can formulate index entries, include classes like `Array`, `String`, and `TypedArray`, which are `Array.prototype.at()`, `String.prototype.at()`, and `%TypedArray%.prototype.at()`, respectively.

Because of this, we can perform the `.at()` method directly on these indexable objects.

## Existing methods for getting list elements

To see the benefits of the `.at()` method, we will quickly walk through some of the existing methods for comparison purposes. This will also serve as a refresher for beginners.

Let’s consider an array of elements called `arr`:

```javascript
const arr = [1, 2, "three", 4, 5, true, false];
```

By using the bracket notation, `[]`, on the `arr` array, we can get an element at a specific index. For instance, `arr[0]` returns the first element, `1`, and so on. But, to get an item from the end of an unknown length, we use the `length` property or the `slice()` method.

### Using the `length` property

The `length` property’s syntax is written as the following:

```javascript
arr[arr.length - N];
```

Here, `N` equals the nth element from the end of a list, and by using the syntax, we can grab any element from the end of that list.

In the following code, we use the syntax to grab the last element of the `arr` array:

```javascript
const arr = [1, 2, "three", 4, 5, true, false];
const lastItem = arr[arr.length - 1];
console.log(lastItem);  // Expected Output: false
```

This works fine, but the syntax can be inconvenient and tedious for a simple task. Besides, one of its drawbacks when working with the returned value of a function compels us to first store the returned value in a variable before applying the syntax:

```javascript
function appendNumber(arr, N) {
  arr.push(N);
  return arr;
}

const tempArr = appendNumber([1, 2, "three", 4, 5, true, false], 6);
console.log(tempArr[tempArr.length - 1]); // Expected Output: 6
```

In the code above, the returned value of the `appendNumber()` function is first stored in the `tempArr` variable before the `length` property is applied.

### The `slice()` method

Developers can also [employ the `slice()` method](https://blog.logrocket.com/javascript-array-methods/slice) to grab the last item of a list using the following syntax:

```javascript
arr.slice(-1)[0]
```

This syntax allows a negative index, something you’ll see in the `.at()` method later in this tutorial.

The negative index here indicates an offset from the end of the array. For instance, `slice(-1)` removes the last item from the back and returns a new array; `slice(-2)` removes the last two, and so on.

But here, the focus is on the last item, hence `slice(-1)` in the syntax. Then, the `[0]` notation selects the item at that index.

Using the syntax, we can grab the last item of the `arr` array like so:

```javascript
const arr = [1, 2, "three", 4, 5, true, false];

console.log(arr.slice(-1)[0]); // Expected Output: false
```

Unlike the `length` property above, this method does not force us to store the returned value of a function before using the syntax. Hence making it more flexible:

```javascript
function appendNumber(arr, N) {
  arr.push(N);
  return arr;
}

console.log(appendNumber([1, 2, "three", 4, 5, true, false], 6).slice(-1)[0]); // 6
```

Nonetheless, the syntax looks odd and doesn’t portray its intention. And of course, it can be inconvenient as well.

### Why not access the last array element with`arr[-1]`?

This question often comes up from JavaScript beginners, especially if they come from a programming language like Python.

The `arr[-1]` notation in JavaScript is a valid object property. Remember everything in JavaScript, including arrays, are objects. So anytime we use the bracket notation, for instance, `arr[0]`, we reference the property of the object with the key `0`.

By rewriting the `arr` array in the object notation, we have something like this:

```javascript
const arr = {
  0: 1,
  1: 2,
  3: "three",
  // ...
};

console.log(arr[0]); // Expected Output: 1
```

In the above code, we don’t have a key `-1`. So, `arr[-1]` returns a value of `undefined`. If the object property has a key `-1`, as seen in the code below, `arr[-1]` returns its corresponding value:

```javascript
const arr = {
  "-1": "valid"
};

console.log(arr[-1]); // Expected Output: valid
```

This means we can’t use the `arr[-1]` to grab the last element because it’s a valid syntax already. To use the negative index syntax to return an element from the end of a list, we will use the `.at()` method.

## The `.at()` syntax

When using the `.at()` syntax, it receives an index of an item to return. When passing a negative index, it counts from the end of the list or string and returns the item or character found. Else, it returns `undefined`:

```javascript
at(index)
```

## The `.at()` method in practice

As mentioned earlier, the `.at()` method receives an index of the item to return. In this section, we will cover its use cases.

Let’s revisit the `arr` array and see how the `.at()` method allows us to seamlessly return an index element:

```javascript
const arr = [1, 2, "three", 4, 5, true, false];

console.log(arr.at(0)); // Expected Output: 1
console.log(arr.at(2)); // Expected Output: "three"
console.log(arr.at(-1)); // Expected Output: false
console.log(arr.at(-3)); // Expected Output: 5
```

When a positive index passes to the `.at()` method, it returns the element at that index. For a negative index, it counts back from the last element in the list and returns the element.

In the above code, `at(-1)` counts one from the end of the array and returns `false`, which is the element found. In the same way, `at(-3)` counts three from the end and returns `5`.

Like arrays, we can do the same for strings:

```javascript
const str = "The last alphabet is z";

console.log(str.at(0)); // Expected Output: T
console.log(str.at(-1)); // Expected Output: z
```

As we can see, this method is pleasant to use. With just `.at(-1)`, we get the last character of the `str` string. If we did the same task with the `length` property, we would have a longer syntax, like so:

```javascript
console.log(str[str.length - 1]); // Expected Output: z
```

### Working with the returned value of a function

The `.at()` method, unlike the `length` property, does not compel us to store the returned value of a function in a variable before we can use it.

The following code outputs the last element pushed to an array:

```javascript
function appendNumber(arr, N) {
  arr.push(N);
  return arr;
}

console.log(appendNumber([1, 2, "three", 4, 5, true, false], 6).at(-1));
// Expected Output: 6
```

In the code, the `.at()` method applies directly to the returned value without first storing the value in a variable.

### The `.at()` method accepts numbers with a decimal

When a number with a decimal passes to the `.at()` method, it considers the value before the decimal point and returns the item at that index.

Let’s take a look at the following code:

```javascript
const arr = [1, 2, "three", 4, 5, true, false];
console.log(arr.at(0.6)); // Expected Output: 1
console.log(arr.at(-3.6)); // Expected Output: 5
```

In the code above, the first console outputs the item at the `0` index while the second console counts three from the end of the array and outputs the found item.

This is beneficial when we want to randomly select an index element. This can be demonstrated with a rock-paper-scissors game project. We can use the `.at()` method syntax to determine a random selection for the computer.

The following code illustrates how we can apply the `.at()` method to randomly select the computer’s choice:

```javascript
const computerOptions = ["rock", "paper", "scissors"];
const randomIndex = Math.random() * computerOptions.length;

console.log(computerOptions.at(randomIndex));
```

![Rock-Paper-Scissors Generator Showing "Paper," "Rock,""Paper"](https://blog.logrocket.com/wp-content/uploads/2021/10/rock-paper-scissors-generator.png)

[Try it yourself on CodeSandbox](https://codesandbox.io/s/wonderful-river-dttqe?file=/script.js).

[With`Math.random()`](https://blog.logrocket.com/building-random-number-generator-javascript-nodejs/), we get a floating-point number between `0` (inclusive) and the array length. Then, when the `.at()` method receives this floating-point number as an index, it considers the value before the decimal point and returns the element at that index.

Using the square bracket notation for the same task is not possible unless we first floor the random number (that is, round the number down to the nearest integer), as seen in the code below:


```javascript
const randomIndex = Math.floor(Math.random() * computerOptions.length);

console.log(computerOptions[randomIndex]);
```

This is because the bracket notation returns an `undefined` value for numbers with decimals:

```javascript
const arr = [1, 2, "three", 4, 5, true, false];
console.log(arr[0.6]); // Expected Output: undefined
```

The `.at()` method saves us the extra steps of using `Math.floor` to floor a random number.

### Browser support

At the time of writing this tutorial, the `.at()` method works pretty well with the popular modern browsers, except a few. See [browser support here](https://caniuse.com/mdn-javascript_builtins_array_at).

![Browser Support For Using The At() Method](https://blog.logrocket.com/wp-content/uploads/2021/10/at-browser-support.png)

## Conclusion

The `.at()` method, as we have seen in this tutorial, is pleasant when grabbing items based on their index. It is also concise to use compared to the preexisting methods.

If you have any questions or contributions, please share them in the comment section. And if you like this tutorial, endeavor to share it around the web.

---

## [LogRocket](https://logrocket.com/signup/): Debug JavaScript errors more easily by understanding the context

Debugging code is always a tedious task. But the more you understand your errors the easier it is to fix them.

[LogRocket](https://logrocket.com/signup/) allows you to understand these errors in new and unique ways. Our frontend monitoring solution tracks user engagement with your JavaScript frontends to give you the ability to find out exactly what the user did that led to an error.

[![LogRocket Dashboard Free Trial Banner](https://blog.logrocket.com/wp-content/uploads/2020/06/reproduce-javascript-errors.gif)](https://logrocket.com/signup/)

LogRocket records console logs, page load times, stacktraces, slow network requests/responses with headers + bodies, browser metadata, and custom logs. Understanding the impact of your JavaScript code will never be easier!

[Try it for free](https://logrocket.com/signup/).