Array sort() method
sort() sorts array elements in place: it modifies the source array, unlike most other iteration methods, and returns a reference to that same array. It works with both numbers and strings, but a correct numeric order is only possible when you pass a comparison function.
Theory
TL;DR
sort()sorts in place and returns the same array, not a new one.- Without a callback the elements are coerced to strings and compared by Unicode code points.
(a, b) => a - bgives ascending order,(a, b) => b - agives descending order.- For strings that must respect language and case, use
localeCompare. - To keep the original intact, sort a copy:
[...arr].sort(...). - Since ES2019 the sort is stable: equal elements keep their original order.
Quick example
const numbers = [1, 10, 2, 5];
numbers.sort();
console.log(numbers); // [1, 10, 2, 5], compared as strings
numbers.sort((a, b) => a - b);
console.log(numbers); // [1, 2, 5, 10]Syntax and the comparison function
array.sort(compareFunction);compareFunction is a callback of this shape:
(a, b) => {
// return a negative value if a should come before b
// return a positive value if a should come after b
// return 0 if the order does not matter
}By default, with no callback, sort() orders elements as strings by Unicode code points, even when they are numbers. That is why numbers without a comparison function end up ordered character by character rather than by value.
const fruits = ['banana', 'apple', 'cherry'];
fruits.sort();
console.log(fruits); // ['apple', 'banana', 'cherry']Sorting numbers, objects and strings
Numbers ascending and descending. The function (a, b) => a - b gives ascending order, (a, b) => b - a gives descending order.
const prices = [100, 500, 200, 50];
prices.sort((a, b) => b - a);
console.log(prices); // [500, 200, 100, 50]Sorting by an object property. The most common scenario in practice, when an array of objects is ordered by a numeric field.
const users = [
{ name: 'Tim', age: 25 },
{ name: 'Alex', age: 30 },
{ name: 'John', age: 20 }
];
users.sort((a, b) => a.age - b.age);
console.log(users);
// [
// { name: 'John', age: 20 },
// { name: 'Tim', age: 25 },
// { name: 'Alex', age: 30 }
// ]Strings alphabetically, ignoring case. localeCompare is the correct way to compare strings while respecting language and case.
const names = ['tim', 'Alex', 'john'];
names.sort((a, b) => a.localeCompare(b, 'en', { sensitivity: 'base' }));
console.log(names); // ['Alex', 'john', 'tim']Sorting by several criteria. When the age is the same, the name decides the order.
const users = [
{ name: 'Tim', age: 25 },
{ name: 'Alex', age: 25 },
{ name: 'John', age: 20 }
];
users.sort((a, b) => {
if (a.age !== b.age) return a.age - b.age;
return a.name.localeCompare(b.name);
});
console.log(users);
// [
// { name: 'John', age: 20 },
// { name: 'Alex', age: 25 },
// { name: 'Tim', age: 25 }
// ]Why [...arr].sort() is the better habit
sort() modifies the source array and returns a reference to it, not to a new array.
const arr = [3, 1, 2];
const sorted = arr.sort();
console.log(sorted); // [1, 2, 3]
console.log(arr); // [1, 2, 3], the very same array, mutated
console.log(arr === sorted); // trueThat is dangerous when the array comes from props, from application state or from a cache: sorting it "just for display" quietly rebuilds data other code relies on, and React or Vue may miss the change because the reference stayed the same. So you copy before sorting.
const sortedCopy = [...arr].sort((a, b) => a - b);The copy costs one pass over the array, and in exchange you get a pure operation with no side effects. In modern environments the built in toSorted() method expresses the same idea: it returns a new array and leaves the original alone.
When to use sort() and when to use other methods
| Goal | Is sort() a good fit |
|---|---|
| Sort numbers or strings | Yes |
| Sort objects by a field | Yes |
| Get a new sorted array without touching the original | Yes, but only through a copy [...arr] |
| Check a condition | No |
| Transform data | No |
A comparison with the neighbouring methods:
| Method | Returns a new array | Mutates the source | Purpose |
|---|---|---|---|
map() | yes | no | transforms elements |
filter() | yes | no | selects elements |
find() | no, returns an element | no | finds the first element |
reduce() | no, returns one value | no | folds into a single result |
sort() | no, returns the same array | yes | sorts elements |
A formula worth memorising: arr.sort((a, b) => a - b) is ascending, arr.sort((a, b) => b - a) is descending.
Common mistakes
1. Sorting numbers without a callback. Elements are compared as strings, so 10 ends up before 2.
[10, 2, 1].sort(); // [1, 10, 2], compared as stringsThe fix:
[10, 2, 1].sort((a, b) => a - b); // [1, 2, 10]2. Not noticing that the source array is mutated.
const a = [3, 1, 2];
const b = a.sort();
console.log(a === b); // true, it is the same object3. Relying on stability in old engines. Before ES2019 the sort could be unstable, and elements with an equal key could swap their relative order. In modern ECMAScript versions sort() is stable.
4. Returning a boolean from the callback. (a, b) => a > b returns true or false rather than a negative number, zero or a positive number, so the resulting order is unpredictable. Always return a number.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.