javascript, frontend

In JavaScript, when it comes to manipulating the order of elements within an array, reverse() and toReversed() are two commonly used methods, each having its unique functionality and application.

Old school reverse()

The reverse() method, a member of JavaScript’s Array.prototype, alters the order of the array’s elements, essentially flipping them. This method performs the operation in-place, implying that it directly modifies the original array.

Let’s consider the example below:

let fruits = ['🍎', '🥭', '🍍'];
console.log(fruits); // Output: ['🍎', '🥭', '🍍']

let reversedFruits = fruits.reverse();
console.log(reversedFruits); // Output: ['🍍', '🥭', '🍎']

// Note: reverse() mutates the original array.
console.log(fruits); // Output: ['🍍', '🥭', '🍎']

In the above code, after applying reverse(), the original fruits array is also reversed. This is because reverse() is a destructive method and modifies the original array in-place.

Introducing toReversed() 🥳

In contrast to reverse(), the toReversed() method does not mutate the original array. Instead, it creates a new array, mirroring the elements of the original array in reverse order. This method comes handy when preserving the initial order of elements is crucial.

Let’s consider a similar example:

let numbers = [10, 20, 30];
console.log(numbers); // Output: [10, 20, 30]

let reversedNumbers = numbers.toReversed();
console.log(reversedNumbers); // Output: [30, 20, 10]

// toReversed() is non-destructive -- the original array remains unchanged.
console.log(numbers); // Output: [10, 20, 30]

In this example, the original numbers array remains unaffected after applying the toReversed() method, exhibiting its non-destructive nature.

Handling sparse arrays with toReversed()

An additional feature of toReversed() is its behaviour with sparse arrays. In JavaScript, a sparse array is an array where some elements are missing. The toReversed() method treats empty slots in sparse arrays as if they hold the undefined value.

console.log([10, , 30].toReversed()); // Output: [30, undefined, 10]

Here, the empty slot in the array is considered as undefined when reversed.

When did the toReversed() method become available?

To enhance the adaptability and fluidity of array manipulation in JavaScript, the ECMAScript 2023 specification brings about a significant proposal named Change Array by Copy.

This proposal enriches the set of methods on Array.prototype by introducing a suite of functions that operate on the array and return a new copy, instead of manipulating the original array. The newcomers to this function suite include toReversed(), toSorted(), toSpliced(), and an additional method named with().

These methods are designed to mirror the behavior of existing methods reverse(), sort(), and splice(), and the typical array element replacement operation performed using bracket notation. However, these new methods ensure that the original array remains unaltered.

toSorted()

The toSorted() method, just like sort(), arranges the array elements in a certain order. The crucial difference is that it does not modify the original array.

let jumbledNumbers = [30, 10, 20];
console.log(jumbledNumbers); // Output: [30, 10, 20]

let orderedNumbers = jumbledNumbers.toSorted();
console.log(orderedNumbers); // Output: [10, 20, 30]

// The original array remains unchanged
console.log(jumbledNumbers); // Output: [30, 10, 20]

toSpliced()

Similarly, toSpliced() acts as a non-destructive version of splice(). It returns a new array, incorporating the changes specified by the arguments, while the original array stays intact.

let oldArray = ['🍎', '🍌', '🥭'];
console.log(oldArray); // Output: ['🍎', '🍌', '🥭']

// In here we just say, start from index 1 and delete 0 elements, and insert '🍊'
let newArray = oldArray.toSpliced(1, 0, '🍊');
console.log(newArray); // Output: ['🍎', '🍊', '🍌', '🥭']

// The original array remains unchanged
console.log(oldArray); // Output: ['🍎', '🍌', '🥭']

with()

Additionally, the with() method is an invaluable tool that replaces an element at a specified index with a given value and returns a new array, without touching the original array.

let initialFruits = ['🍎', '🍌', '🥭'];
console.log(initialFruits); // Output: ['🍎', '🍌', '🥭']

let updatedFruits = initialFruits.with(1, '🍊');
console.log(updatedFruits); // Output: ["🍎", "🍊", "🥭"]

// The original array remains unchanged
console.log(initialFruits); // Output: ['🍎', '🍌', '🥭']

The motivation behind these new methods

Incorporating these methods in the language specification echoes the increasing emphasis on promoting functional programming styles in JavaScript, where data is usually treated as immutable. This development is a welcome addition for developers who frequently need to perform operations on arrays but wish to keep the original arrays unmodified.

For me personally, these new features significantly simplify array manipulation, particularly in scenarios where avoiding side effects is critical. By preventing accidental mutations, these methods make the code more predictable and easier to reason about, which is a key factor in reducing bugs and enhancing code readability.

Conclusion

The ECMAScript 2023 ‘Change Array by Copy’ proposal introduces four powerful methods that align JavaScript with modern functional programming practices: toReversed(), toSorted(), toSpliced(), and with(). These non-destructive alternatives keep your original arrays untouched, making code more predictable and safer, especially when working with frameworks like React that rely on immutability.

Supported in modern browsers (Chrome 110+, Firefox 115+, Safari 16+), in my opinion, these methods should be your default choice for array manipulation. Use the traditional mutating methods only when you explicitly need in-place modification.

Happy coding! 🚀

Well, now what?

You can navigate to more writings from here. Connect with me on LinkedIn for a chat.

  1. 2026

    1. We Might All Be AI Engineers Now
      March 05

      ai, engineering, tools, agents

    2. The Hardest Bug I Ever Fixed Wasn't in Code
      February 07

      engineering, career

    3. Why I Switched to Podman (and Why You Might Too)
      February 02

      docker, tools, linux

  2. 2024

    1. The World is Stochastic
      October 18

      career, philosophy

    2. Debugging a running Java app in Docker
      May 29

      java, docker, debugging

    3. Why is it UTC and not CUT?
      February 21

      time, history

  3. 2023

    1. Deep prop drilling in ReactJS
      December 26

      react, javascript, frontend

    2. Eigenvectors
      October 24

      math, linear-algebra

    3. Java's fork/join framework
      October 21

      java, concurrency

    4. TypeScript's omit and pick
      August 10

      typescript, frontend

    5. JavaScript's new immutable array methods
      June 28

      javascript, frontend

    6. Integrating JUnit 5 in Maven projects
      May 25

      java, testing

    7. My take on ChatGPT and prompt engineering
      March 11

      ai, prompts

    8. Declarative events in ReactJS
      March 09

      react, javascript, frontend

    9. Positive Lookaheads
      March 07

      regex, tools

    10. Functors
      March 06

      functional-programming, math

    11. Fast forward videos with ffmpeg
      January 18

      ffmpeg, tools

    12. Rotate y-axis of a 2D vector
      January 05

      math, vectors

  4. 2022

    1. Synchronizing time
      December 31

      distributed-systems, time

    2. Vector rotation
      November 20

      math, vectors

    3. Sed find and replace
      November 14

      sed, tools, linux

    4. Asgardeo try it application
      September 06

      identity, iam, asgardeo

    5. Flatten error constraints
      August 11

      java, algorithms

    6. Good Git commit messages
      July 24

      git, engineering

    7. Asgardeo JIT user provisioning
      March 09

      identity, iam, asgardeo

    8. Monotonic Arrays
      February 25

      algorithms, javascript

    9. How GOROOT and GOPATH works
      February 01

      go, tooling

  5. 2021

    1. Two summation
      November 21

      algorithms