Sorting Arrays in JavaScript
The Array.prototype.sort() method is powerful but frequently misunderstood due to its default behavior. It sorts the elements of an array in place (mutating the original array) and returns the reference to the same array.
1. The Default Behavior (String Sorting)
By default, the sort() method converts all elements to strings and compares their sequences of UTF-16 code units values.
const fruits = ['Banana', 'Orange', 'Apple', 'Mango'];
fruits.sort();
// ['Apple', 'Banana', 'Mango', 'Orange']
const numbers = [1, 30, 4, 21, 100000];
numbers.sort();
// [1, 100000, 21, 30, 4]
// Wait, what? 100000 comes before 21 because '1' comes before '2' in string comparison!
To sort numbers correctly, you must provide a compare function.
2. The Compare Function
To customize the sorting logic, you pass a compare function: array.sort((a, b) => { ... }).
The function determines the order of the two elements a and b:
- If it returns
< 0,acomes beforeb. - If it returns
> 0,bcomes beforea. - If it returns
0, the order remains unchanged.
Sorting Numbers Correctly
const numbers = [1, 30, 4, 21, 100000];
// Ascending order
numbers.sort((a, b) => a - b);
// [1, 4, 21, 30, 100000]
// Descending order
numbers.sort((a, b) => b - a);
// [100000, 30, 21, 4, 1]
3. Sorting Complex Objects
When dealing with arrays of objects, the compare function is essential for sorting by specific properties.
const users = [
{ name: 'John', age: 34 },
{ name: 'Amy', age: 20 },
{ name: 'Zack', age: 29 }
];
// Sort by age (Ascending)
users.sort((a, b) => a.age - b.age);
// Sort by name (Alphabetical)
users.sort((a, b) => {
if (a.name < b.name) return -1;
if (a.name > b.name) return 1;
return 0;
});
4. localeCompare for Strings
When sorting strings, standard comparison (< and >) might fail with special characters or accents (e.g., 'é' vs 'e'). Use String.prototype.localeCompare() for robust alphabetical sorting.
const names = ['Réservé', 'Premier', 'Cliché', 'Commun', 'Café', 'Adieu'];
names.sort((a, b) => a.localeCompare(b, 'fr'));
// ['Adieu', 'Café', 'Cliché', 'Commun', 'Premier', 'Réservé']
5. Sort Stability
Since ES2019 (ES10), JavaScript guarantees that the sort() method is stable.
A stable sort means that if two elements have the same sorting priority, they will retain their relative order from the original array.
const students = [
{ name: 'Alex', grade: 90 },
{ name: 'Ben', grade: 80 },
{ name: 'Carl', grade: 90 }
];
// Sort by grade descending
students.sort((a, b) => b.grade - a.grade);
// Alex and Carl both have 90. Because of stability, Alex will ALWAYS appear before Carl in the sorted array, just as in the original.
6. Non-Mutating Sort: toSorted()
Introduced recently, toSorted() works identically to sort() but returns a new array, leaving the original array completely untouched.
const original = [3, 1, 2];
const sorted = original.toSorted((a, b) => a - b);
console.log(sorted); // [1, 2, 3]
console.log(original); // [3, 1, 2] (Unchanged!)