You will be able to order JavaScript arrays correctly by using sort() with a comparator, avoiding the default string-sorting gotcha.
What it is
Array.prototype.sort() reorders the elements of an array in place and returns the same array. If you call it without a comparator, JavaScript converts each element to a string and compares those strings by character code. That is why numbers can sort in an unexpected order: "10" comes before "2" because the first character "1" is less than "2".
Related terms: comparator (the callback that decides order), lexicographic order (string-like ordering), and stable sort (equal elements keep their original relative order in modern JavaScript).
Why it matters
- It lets you display lists in a predictable order, such as scores, names, or dates.
- It helps you find the smallest or largest value by sorting and reading the first or last element.
- It supports grouping and searching when data is ordered.
- It avoids bugs caused by assuming numbers sort numerically by default.
Syntax or steps
The smallest useful pattern is to pass a comparator function to sort():
array.sort((a, b) => {
return a - b;
});
The comparator receives two elements. Return a negative number if a should come before b, a positive number if b should come before a, or 0 if they are equal. For ascending numbers, use a - b. For descending numbers, use b - a. For strings, use a.localeCompare(b).
Example
const scores = [10, 2, 33, 4];
const numericAscending = scores.slice().sort((a, b) => a - b);
const numericDescending = scores.slice().sort((a, b) => b - a);
const defaultStringSort = scores.slice().sort();
console.log(numericAscending);
console.log(numericDescending);
console.log(defaultStringSort);
Part-by-part explanation
scores.slice()creates a copy so the originalscoresarray is not changed..sort((a, b) => a - b)compares numbers numerically, producing[2, 4, 10, 33]..sort((a, b) => b - a)reverses the numeric comparison, producing[33, 10, 4, 2]..sort()uses the default string comparison, producing[10, 2, 33, 4]because"10"sorts before"2".
Common mistakes
- Sorting numbers without a comparator. Fix it by adding
(a, b) => a - b. - Forgetting that
sort()mutates the original array. Fix it by copying first withslice(), or by usingtoSorted()where supported. - Returning a boolean from the comparator. A comparator should return a number, not
trueorfalse. - Using default sorting for user-facing text. It may ignore locale rules; use
localeCompare()for strings.
When to use it
Use sort() when you need a complete ordering and you are okay with changing the array. If you need to keep the original array unchanged, compare it with a copy or with toSorted().
| Need | Use | Why |
|---|---|---|
| Sort numbers in place | arr.sort((a, b) => a - b) | Simple and efficient for full ordering. |
| Sort without changing original | arr.slice().sort((a, b) => a - b) | Works in all JavaScript environments. |
| Sort without changing original, modern code | arr.toSorted((a, b) => a - b) | Returns a new sorted array if supported. |
| Sort strings by language rules | arr.sort((a, b) => a.localeCompare(b)) | Handles accents and locale ordering better. |
Practice
Guided exercise: Sort [5, 2, 10, 1] from smallest to largest. Expected output: [1, 2, 5, 10].
Challenge: Sort these objects by price from highest to lowest: [{ price: 10 }, { price: 5 }, { price: 20 }]. Hint: compare b.price - a.price.
Quick check
Why does [10, 2, 33, 4].sort() not produce [2, 4, 10, 33]?
Because the default sort converts values to strings and compares them character by character, so "10" comes before "2".
Summary
JavaScript arrays sort as strings unless you provide a comparator. For numbers, use a subtraction comparator; for strings, use localeCompare(). Remember that sort() changes the original array, so copy it first when needed.