Array.prototype.reverse()
Reverses the order of an array's elements in place and returns a reference to that same array.
reverse()- Added in JavaScript ES1
Return value
ArrayThe reference to the original array, now reversed. Note that the array is reversed in place, and no copy is made.
Errors
Throws a TypeError when called on a frozen array or when a target index is non-writable in strict mode.
Changelog
- PHP ES1Present on Array.prototype from the first edition of the language.
- PHP ES2023toReversed() added as the non-mutating counterpart.
reverse() transposes an array's elements in place: the first becomes the last, the last becomes the first. It returns the same array it modified, not a copy, so the returned value and the original are one object.
When to reach for it
Use it to flip a chronological list into newest-first, to build a list by pushing and reversing once at the end (linear, where repeated unshift() is quadratic), or to reverse a string via split("").reverse().join("") for plain ASCII.
What trips people up
The alias trap: const backwards = list.reverse() reads like it produced a second array, but backwards === list, and list is now reversed too. Every other reference to that array sees the new order. Copy first with [...list].reverse(), or use toReversed(), which returns a new array and leaves the source alone.
Chaining after sort() looks harmless but mutates twice: arr.sort().reverse() is best replaced by a descending comparator.
String reversal by this route breaks on emoji and other characters outside the Basic Multilingual Plane, because split("") splits UTF-16 code units and tears surrogate pairs apart. Use [...str] to split by code point instead.
Example
When to use it
- Show a chronological log newest-first without re-sorting
- Finish a list built with push() that needs to end up in reverse order
- Reverse a plain ASCII string through split, reverse, and join
- Walk paired data structures back to front after processing
Frequently asked questions
Does reverse() return a new array?
No, it reverses the array in place and returns a reference to the same array; use toReversed() or [...arr].reverse() when you need a separate copy.
How do I reverse an array without changing the original?
Copy it first with [...arr].reverse() or arr.slice().reverse(), or call arr.toReversed(), which is the non-mutating counterpart added in ES2023.
Why does reversing a string with emoji produce garbage?
split("") breaks the string into UTF-16 code units and splits surrogate pairs; spread the string with [...str] instead so it is divided by code point.
More examples
The aliasing trap
Both log and view point at one array, so reversing through either changes what the other sees. Spreading into a fresh array before reversing is the fix when other code holds a reference.
const log = ["a", "b", "c"];
const view = log;
const flipped = log.reverse();
console.log(flipped); // ['c','b','a']
console.log(view); // ['c','b','a'] — the other reference changed too
const safe = ["a", "b", "c"];
console.log([...safe].reverse()); // ['c','b','a']
console.log(safe); // ['a','b','c']Reversing strings safely
split("") cuts by UTF-16 code unit, so the two halves of the emoji are separated and reassembled in the wrong order. Spreading the string iterates by code point and keeps the character intact.
const ascii = "hello";
console.log(ascii.split("").reverse().join("")); // olleh
const emoji = "ab🙂";
console.log(emoji.split("").reverse().join("")); // broken surrogate pair
console.log([...emoji].reverse().join("")); // 🙂baDescending order without a double mutation
Sorting then reversing traverses the array twice; a descending comparator does it in one pass with the same result. The final line shows toReversed(), which returns a new array and never touches the source.
const scores = [3, 1, 4, 1, 5];
console.log([...scores].sort((a, b) => a - b).reverse()); // [5,4,3,1,1]
console.log([...scores].sort((a, b) => b - a)); // [5,4,3,1,1]
console.log(scores); // [3,1,4,1,5]
console.log([1, 2, 3].toReversed()); // [3,2,1] — non-mutating
Discussion