reverse()

ES3+

Reverses an array in place and returns the reference to the same array.

Syntax

array.reverse()

Return Value

Array

The reversed array

Examples

JavaScript
const numbers = [1, 2, 3, 4, 5];
numbers.reverse();
console.log(numbers);
Output:
// [5, 4, 3, 2, 1]

📌 When to Use

Use reverse() when the order of an array should be flipped end-to-end and mutating that array is acceptable - typically to convert between oldest-first storage order and newest-first display order, to flip an ascending sort into a descending one you just produced, or to process items back-to-front. The mutation question is the first fork in the road: reverse() rewrites the array you call it on AND returns that same reference, which reads like a safe transformation but is not. When the source must survive - props in React, data shared between modules, anything another consumer might read - use toReversed() (ES2023) or copy first with [...arr].reverse(). Two situations make reverse() unnecessary altogether. If the array came from your own sort(), reverse the comparator instead: (a, b) => b.date - a.date sorts descending directly, one pass instead of two, with no stability subtleties. And if you only need to iterate backwards without changing anything, a simple index-decrementing for loop touches nothing and allocates nothing. Rendering chat messages, commit logs, and notification feeds newest-first is the canonical everyday use, since APIs and databases usually deliver chronological order.

⚠️ Common Mistakes

Writing const reversed = arr.reverse() and believing arr is still in original order. reverse() mutates in place and returns the SAME array object, so arr and reversed are two names for one flipped array. The assignment makes the code look non-destructive, which is precisely why this bug slips through review.

Reversing framework state or props in place. messages.reverse() inside a component body mutates data the framework believes unchanged (same reference), so renders go stale or double-reversal occurs on re-render - the list flips back and forth as the component updates. Derive a reversed copy instead: toReversed() or [...messages].reverse().

Chaining as if reverse() were pure: arr.reverse().slice(0, 5) does return the first five of the reversed order, but it also permanently flipped arr as a side effect. Chains hide mutations mid-expression - the damage only surfaces later when other code reads the array and finds it backwards.

Reversing a string via split("").reverse().join("") on text that may contain emoji or non-Latin characters. split("") slices by UTF-16 code units, so surrogate pairs shatter into invalid halves and combining accents detach. Use [...str].reverse().join("") to split by code points, and be aware even that breaks multi-codepoint clusters like flag emoji.

Calling reverse() twice by accident - once in a data-preparation step and again in the view layer. Because the operation is its own inverse, the symptom is data that LOOKS correctly ordered in simple tests but flips depending on which code path ran, making the bug appear intermittent.

✅ Best Practices

Default to toReversed() in ES2023+ targets: it returns a fresh reversed array, never touches the source, and states its intent in the name. Where older environments matter, [...arr].reverse() is the drop-in equivalent - the spread creates the sacrificial copy that reverse() is then free to mutate.

Skip the reverse entirely when a comparator can produce the target order: sort((a, b) => b.score - a.score) yields descending order in one operation. Reserve reverse() for flipping orders you did not create yourself, such as API responses with fixed chronological ordering.

Adopt a simple ownership rule: mutate only arrays your current function created. If the array arrived as a parameter, from a store, or from a cache, copy before reversing - the one-allocation cost is trivial compared to debugging action-at-a-distance order corruption.

For pure backwards iteration, prefer a decrementing for loop or arr.at(-1 - i) indexing over materializing a reversed copy - zero allocation, and the reading order is explicit in the loop header where reviewers expect to find it.

In CSS-adjacent cases, consider whether the DOM even needs reversed data: flex-direction: column-reverse renders newest-first chat UIs from chronologically ordered markup, keeping the data layer untouched and scroll-anchoring behavior intact.

⚡ Performance Notes

reverse() swaps pairs from the two ends toward the middle: n/2 swaps, O(n) time, zero allocation - as cheap as reordering can be, and V8 executes it on packed arrays as tight native code. The immutable variants add exactly one array allocation: [...arr].reverse() and toReversed() are both O(n) time and O(n) space, which still costs microseconds for tens of thousands of elements. Reversal is memory-bandwidth-bound rather than compute-bound, so even million-element arrays flip in low milliseconds; if reverse() ever dominates a profile, the real problem is usually calling it repeatedly (per render, per event) on data that did not change - memoize the derived reversed array or store the data in the desired order to begin with. One structural note: on sparse arrays, reversing relocates the holes as well and can force the engine through slower generic paths, another of the many reasons to keep arrays packed.

🌍 Real World Example

Displaying Messages in Chronological Order

Message feeds expose the storage-versus-display ordering mismatch perfectly: APIs return conversations oldest-first (natural for appending and for reading history), while UIs usually want the newest message at the top. The example keeps the fetched array pristine and derives a reversed copy for display - note the spread-before-reverse in both the plain and the React variants, which is the load-bearing detail; reversing prev in place inside a state updater would corrupt the very state being updated. The string-reversal snippet at the end shows the adjacent classic, with the caveat that split("") is only safe for basic ASCII-range text - use [...str] for anything that might contain emoji.

// Messages from API are sorted oldest first
const messages = await fetchMessages();  // [{id: 1, time: '10:00'}, ...]

// Display newest first without modifying original
const displayMessages = [...messages].reverse();

// For React state (always copy first)
setMessages(prev => [...prev].reverse());

// Reverse a string
const original = 'Hello';
const reversed = original.split('').reverse().join('');
// reversed: 'olleH'

Related Methods