# Everything about the new array methods in JavaScript

One of the promises of ECMAScript is the addition of new array methods. In this article we'll go through every one of them and give a use case for each, so you won't be left out!

- URL: https://blog.lsantos.dev/en/everything-about-the-new-array-methods-in-javascript/
- Published: 2022-09-22
- Updated: 2026-07-16
- Section: javascript
- Tags: javascript, ecmascript, development, nodejs
- Language: en
- Author: Lucas Santos

---
Once again let's chat about the main new features in JavaScript! This time we'll talk about one of the coolest [proposals](https://github.com/tc39/proposal-change-array-by-copy) out there right now. Today it's at stage 3, which means it'll be live soon!

If you don't know how JavaScript works, in this video I explain a bit more about the process behind releasing new JavaScript features. If you haven't watched it yet, I strongly recommend it so you can understand how everything works better!

![](https://www.youtube.com/watch?v=hDQu3AvvDfg)

## The problem

As a lot of people have found out the hard way, arrays and objects in JavaScript are passed by reference because they're created and stored on the Heap (which I won't explain here, but [this article](https://fjolt.com/article/javascript-by-reference-by-value) gives you a good idea). Because of that, they're created only once and passed to functions as a pointer to the original object.

So when we perform some operation on them, for example reversing an array with `reverse()`, we always change the original array:

```js
const arr = [1,2,3]
arr.reverse()
console.log(arr) // [3,2,1]
```

And that's the cause of tons and tons of problems in most systems. Over time, we learned to use object cloning to create a copy of that array and make the change instead, for example:

```js
const arr = [1,2,3]
const reversed = [...arr].reverse()
console.log(arr) // [1,2,3]
console.log(reversed) // [3,2,1]
```

When we use the spread operator `[...` what we're doing is cloning the array element by element and applying the `reverse` method to this new array we get back.

And that's true for several other methods like `splice` and `sort`. Why don't we just change that?

## The proposal

The idea behind this proposal is to add 4 new methods to arrays:

-   `Array.prototype.toReversed() -> Array`
-   `Array.prototype.toSorted(compareFn) -> Array`
-   `Array.prototype.toSpliced(start, deleteCount, ...items) -> Array`
-   `Array.prototype.with(index, value) -> Array`

These functions don't need much explaining, but I'll give you a basic idea of each one so you understand what's going on. The important part here is that **all these functions are non-destructive**, meaning they don't touch the original object: they all return a new array with the changes.

### `toReversed`

It does the same thing as our second example: it reverses an array and returns the reversed copy of that array, without modifying the original.

```js
let x = [ 1, 2, 3 ];
let y = x.toReversed();

// [ 1, 2, 3 ], [ 3, 2, 1 ]
console.log(x, y);
```

### `toSorted`

Just like the previous one and its `sort` counterpart, this function sorts an array following a sorting function without modifying the original array. By default, the sorting function takes the array and sorts it numerically like this:

```js
let x = [ 5, 3, 4, 2, 1 ];
let y = x.toSorted(); // [ 1, 2, 3, 4, 5 ]
```

But just like `sort`, it accepts a sorting function that follows a `(a, b) => number` signature, where if:

-   The return is `>0`, `a` comes after `b`
-   The return is `<0`, `a` comes before `b`
-   The return is `0`, nothing changesYou can find this documentation on [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort).

```js
let x = [
    { value: 0 },
    { value: 4 },
    { value: 2 },
    { value: 3 }
];

// y will be:
// [
//    { value: 0 },
//    { value: 2 },
//    { value: 3 },
//    { value: 4 }
// ]
let y = x.toSorted((a, b) => {
    return a.value - b.value
});
```

### `toSpliced`

The `splice` method isn't the same as the `slice` method. While `slice` returns a subset of the original array **in a new array**, `splice` changes the array's content in three ways:

-   Adding items anywhere in the array
-   Removing items anywhere in the array
-   Replacing one item with another anywhere in the array

The problem is it also did this to the array it received. This new version returns a fresh copy instead.

The function keeps the same signature, just with a new return type: `(start, deleteCount, ...items) => Array`, where:

-   `start` is the position to start counting from, or where the pointer begins
-   `deleteCount` is the number of items to remove starting from `start`
-   `...items` is an optional parameter that, if passed, sets the new value at position `start` after removing all the items from `deleteCount`This example actually shows very well why these functions are good. If we modified the array in the original array itself, we'd have to recreate `x` every time.

```js
let x = [ "Cachorro", "Gato", "Zebra", "Morcego", "Tigre", "Leão" ];

// y is [ "Cachorro", "Cobra", "Morcego", "Tigre", "Leão" ]
let y = x.toSpliced(1, 2, "Cobra");

// z is [ "Cachorro, "Tigre", "Leão" ]
let z = x.toSpliced(1, 3);
```

> This example actually shows very well why these functions are good. If we modified the array in the original array itself, we'd have to recreate `x` every time

### `with`

This is a new function that simplifies using splice a bit when we only need to modify a single element of the array. Originally, if we wanted to modify this array:

```js
let x = [ "Cachorro", "Gato", "Zebra", "Morcego", "Tigre", "Leão" ];
```

To show "Cobra" instead of "Gato", we'd have to do this with `splice`:

```js
let y = x.toSpliced(1, 1, "Cobra");
```

But with `with` we can do this:

```js
// [ 'Cachorro', 'Cobra', 'Zebra', 'Morcego', 'Tigre', 'Leão' ]
x.with(1, "Cobra")
```

Essentially what we're saying is: "Take array x, at position 1, and show it **with** this other value."

## Support

Support isn't implemented in every browser yet, but you can use the [polyfills](https://github.com/tc39/proposal-change-array-by-copy/blob/main/polyfill.js) available on TC39 to implement this feature. If you're using Node, you can use [`core-js`](https://github.com/zloirock/core-js#change-array-by-copy) to test it out. Your code would look something like this:

```js
require('core-js/proposals/change-array-by-copy')

const sequencia = [1, 2, 3]
console.log(sequencia.toReversed()) // => [3, 2, 1]
console.log(sequencia) // => [1, 2, 3]

const desordenado = new Uint8Array([3, 1, 2])
console.log(desordenado.toSorted()) // => Uint8Array [1, 2, 3]
console.log(desordenado) // => Uint8Array [3, 1, 2]

const precisaDeCorrecao = [1, 1, 3]
console.log(precisaDeCorrecao.with(1, 2)) // => [1, 2, 3]
console.log(precisaDeCorrecao) // => [1, 1, 3]

const spliced = [1, 2, 3]
console.log(spliced.toSpliced(1, 1)) // => [1, 3]
console.log(spliced) // => [1, 2, 3]

let x = [ "Cachorro", "Gato", "Zebra", "Morcego", "Tigre", "Leão" ];
console.log(x.toSpliced(1,1,"Cobra"))
console.log(x.with(1, "Cobra"))
```

This feature is expected to ship in the next ECMAScript version, along with a bunch of super cool features I've already talked about [here](/o-futuro-do-js/).
