How-To

How-To · Arrays

How to Sort an Array in JavaScript

Sort numbers, strings, and objects correctly with Array.prototype.sort() — and avoid the default-sort trap that turns [10, 1, 2] into [1, 10, 2].

XCODXHow-To · Updated

Overview

JavaScript sorts arrays with Array.prototype.sort(). It works — but with one big surprise: by default it sorts elements as strings, so [10, 1, 2].sort() gives [1, 10, 2], not [1, 2, 10]. To sort correctly you almost always pass a compare function.

Steps

1. Sort numbers with a compare function

const nums = [10, 1, 21, 2];

nums.sort((a, b) => a - b); // ascending  → [1, 2, 10, 21]
nums.sort((a, b) => b - a); // descending → [21, 10, 2, 1]

2. Sort strings

The default sort already orders plain ASCII strings alphabetically, but it puts capital letters before lowercase ones. For human-friendly, locale-aware ordering, use localeCompare:

['banana', 'Apple', 'cherry'].sort();
// ['Apple', 'banana', 'cherry']  — capital A sorts first

['banana', 'Apple', 'cherry'].sort((a, b) => a.localeCompare(b));
// ['Apple', 'banana', 'cherry']  — and handles accents/locales correctly

3. Sort objects by a property

const users = [
  { name: 'Ada', age: 36 },
  { name: 'Bo', age: 22 },
  { name: 'Cy', age: 29 },
];

users.sort((a, b) => a.age - b.age);
// Bo (22), Cy (29), Ada (36)

users.sort((a, b) => a.name.localeCompare(b.name)); // by name

4. Sort without changing the original

sort() mutates the array in place. To keep the original, copy it first — with the spread operator, or with the newer non-mutating toSorted():

const original = [3, 1, 2];

const sorted = [...original].sort((a, b) => a - b); // copy, then sort
console.log(original); // [3, 1, 2] — untouched
console.log(sorted);   // [1, 2, 3]

// Newer engines (2023+) offer a built-in non-mutating version:
const also = original.toSorted((a, b) => a - b); // [1, 2, 3]

Runnable example

Edit and run — try changing the compare function:

Common pitfalls

One thing you can rely on: JavaScript's sort is stable — elements the compare function treats as equal keep their original relative order, which matters when you sort by one field after another.

Frequently asked questions

Why does [10, 1, 2].sort() give [1, 10, 2]?
By default sort() converts elements to strings and compares them character by character, so '10' sorts before '2' (because '1' < '2'). Pass a compare function (a, b) => a - b to sort numerically.
How do I sort in descending order?
Reverse the compare function: array.sort((a, b) => b - a) for numbers, or array.sort((a, b) => b.localeCompare(a)) for strings.
Does sort() change the original array?
Yes — sort() sorts in place and returns the same array. Copy first with [...array].sort(...), or use the non-mutating toSorted() (available in modern engines) to leave the original untouched.
How do I sort an array of objects by a property?
Return the difference of a numeric field, e.g. users.sort((a, b) => a.age - b.age), or use localeCompare for string fields: users.sort((a, b) => a.name.localeCompare(b.name)).