
Reverse an Array in JavaScript

It's really common to be tasked with reversing an array in JavaScript, whether you're displaying items in reverse order or processing data from end to start. As you will probably know, JavaScript offers the in‑built .reverse() method, which makes this task simple. However, there is more to reversing arrays than meets the eye, especially when it comes to immutability.
Today, I intend to explore how to reverse arrays in JavaScript, the caveats of using .reverse(), and touch upon some of the older methods that you might encounter for reversing arrays. By the end, you should hopefully understand the best approaches for reversing arrays without unintended side effects.
The .reverse() Method
Any relatively seasoned front‑end developer will be familiar with the .reverse() method. This is the most straightforward way to reverse an array in JavaScript, and looks something like this:
const originalArray = [1, 2, 3, 4, 5];const reversedArray = originalArray.reverse();console.log(reversedArray); // Output: [5, 4, 3, 2, 1]At first glance, this all looks very straightforward and ‑ perhaps unusually for JavaScript development ‑ very logical. You might appreciate, though; this wouldn't exactly be a very long or interesting article if there wasn't at least one catch. In this case, there's a critical detail to be aware of: .reverse() mutates the original array.
The Mutation Problem
In layman's terms, a mutating method changes the original source data as well (our array). This means that your original (named) variable is now backwards, which can very quickly lead to unexpected behaviour, especially when the same array is referenced elsewhere in your code:
const numbers = [1, 2, 3, 4, 5];const reversed = numbers.reverse();console.log(numbers); // Output: [5, 4, 3, 2, 1] (original array is modified)As you can see in the example above, even though we've defined a new const (reversed) for the backwards version of the array, the original const (numbers) has also now been reversed (mutated).
This is a side effect that can cause bugs, especially in larger applications where data immutability is crucial.
Reversing Without Mutating
So, to reverse an array without mutating the original, we need to create a shallow copy first. The most common approach for this is to use the spread operator, like this:
const originalArray = [1, 2, 3, 4, 5];const reversedArray = [...originalArray].reverse();console.log(originalArray); // Output: [1, 2, 3, 4, 5] (unchanged)console.log(reversedArray); // Output: [5, 4, 3, 2, 1]With this approach, we can maintain immutability, and align our practices with those used in methods like .map() and .filter(), which return new arrays rather than altering the original.
Why Immutability Matters
It may well be that you never intend to use the original const again, so it doesn't matter for your specific usecase. However, immutability helps prevent unintended side effects and makes our code easier to:
Debug:
Since data isn't unexpectedly changing, it's easier to track down issues.Maintain:
Immutability leads to more predictable code, reducing hidden dependencies.Optimise:
Many modern frameworks (like React) rely on immutability for performance optimisations.
Alternative Methods of Reversing an Array
The .reverse() method has been available since ECMAScript 1 (1997), so it is safe to say that you are going to struggle to find any JavaScript environment in use today that doesn't support it ‑ it quite literally predates even IE6! Nevertheless, it would be amiss of for me to not at least explore legacy solutions with JavaScript fundamentals.
Using a for Loop
The most straightforward ‑ legacy ‑ alternative to .reverse() would be to use a for loop, like this:
const reverseArray = (arr: number[]): number[] => { const result: number[] = []; for (let i = arr.length - 1; i >= 0; i--) { result.push(arr[i]); } return result;};const original = [1, 2, 3, 4, 5];console.log(reverseArray(original)); // Output: [5, 4, 3, 2, 1]Here we simply loop over the original array backwards, pushing our new order into a new variable. This approach doesn't mutate the original array and is still efficient, although perhaps less concise than using the spread operator and .reverse().
Using reduce()
Using reduce() ‑ which wasn't introduced until December 2009 as part of ECMAScript 5 ‑ certainly isn't going to win us any 'legacy alternative to .reverse()' rewards. Even so, it does offer an alternative that removes mutation, and is worth exploring simply as a way to discuss the way JavaScript works and the many ways it can be used to achieve the same thing. I wouldn't even suggest this is a viable production alternative, just an experiment and discussion point.
So, using reduce() to reverse an array looks like this:
const originalArray = [1, 2, 3, 4, 5];const reversedArray = originalArray.reduce((acc, curr) => [curr, ...acc], []);console.log(reversedArray); // Output: [5, 4, 3, 2, 1]This method avoids mutation, but it is less performant for large arrays due to the repeated use of the spread operator inside of the accumulator. As I say, it's not worth attempting in a production environment!
Wrapping up
Reversing an array in JavaScript is straightforward with .reverse(), but being aware of its mutating behaviour is crucial ‑ and something I've often seen developers tripped up by. By using techniques like spreading into a new array, you can maintain immutability, making your code more predictable and maintainable.
Key Takeaways
- The
.reverse()method mutates the original array. - Use
[...array].reverse()to reverse without mutation, promoting immutability. - Older methods like
forloops, and newer methods likereduce()offer alternative, non‑mutating solutions but probably wouldn't be suitable in production. .reverse()has been available since ECMAScript 1 (1997), so it's universally supported.
Understanding both modern and traditional approaches gives you flexibility and deeper insight into JavaScript's capabilities.
Related Articles

Preventing and Debugging Memory Leaks in React. 
Testing Vue Components with Vue Test Utils. Testing Vue Components with Vue Test Utils

Building Custom Hooks in React. Building Custom Hooks in React

Promises in JavaScript: An Introduction. Promises in JavaScript: An Introduction

The LeetCode Zigzag Conversion Problem in TypeScript. The LeetCode Zigzag Conversion Problem in TypeScript

Cleaning up Your JavaScript Code: The Double Bang (!!) Operator. Cleaning up Your JavaScript Code: The Double Bang (
!!) Operator
Block Bad Bots Using .htaccess. Block Bad Bots Using
.htaccess
How to Amend Git Commits. How to Amend Git Commits

Semantic HTML. Semantic HTML

Removing p Tags from Contentful List Items. Removing
pTags from Contentful List Items
Finding the Median of Two Sorted Arrays with JavaScript. Finding the Median of Two Sorted Arrays with JavaScript

How to Prevent Race Conditions in JavaScript with AbortController. How to Prevent Race Conditions in JavaScript with
AbortController