Sorting Arrays

JavaScript ES6+ · ✓ verified by execution on 2026-08-13

When building applications, you will frequently need to display data in a specific order: highest scores first, oldest users last, or names arranged alphabetically. In JavaScript, the primary tool for this job is the sort() method. While it seems simple at first glance, sort() hides several surprising default behaviors that every JavaScript developer must learn to navigate. Let’s explore how it works and how to master the compare function.

The Default String Sort

By default, the sort() method sorts elements alphabetically. It does this by temporarily converting every element in the array into a string, and then comparing their sequences of UTF-16 code unit values. For arrays of strings, this works exactly as you would expect.

javascript
const months = ['March', 'Jan', 'Feb', 'Dec'];
months.sort();
console.log(months);
Output
[ 'Dec', 'Feb', 'Jan', 'March' ]

However, this default behavior leads to one of the most infamous and confusing traps in JavaScript when you try to sort an array of numbers. Because the numbers are converted to strings first, the character "1" comes before the character "2" in the UTF-16 alphabet, meaning 100000 will be sorted before 21. Try predicting the output of the following code!

Predict the output javascript

Read the code. What exactly will it print? Commit to an answer before you look.

const nums = [1, 30, 4, 21, 100000];
nums.sort();
console.log(nums);
Output
[ 1, 100000, 21, 30, 4 ]

Mastering the Compare Function

To sort numbers (or objects) correctly, you must bypass the default string conversion by providing your own compare function. The sort() method will call your function repeatedly, passing in two elements at a time (commonly named a and b). Your function’s job is to return a number that dictates their order:

For numbers, the simplest way to achieve this ascending order is by returning the result of a - b. If a is smaller than b, the result is negative, placing a first! Let’s watch this compare function evaluate pairs of elements step-by-step:

javascript · visualize
const nums = [1, 30, 4, 21, 100000];
nums.sort((a, b) => a - b);
console.log(nums);

To sort in descending order (highest to lowest), you simply swap the subtraction to b - a.

javascript
const nums = [1, 30, 4, 21, 100000];
nums.sort((a, b) => b - a);
console.log(nums);
Output
[ 100000, 30, 21, 4, 1 ]

The Mutation Trap

Unlike methods like map() or filter(), which return a completely new array, sort() sorts the elements in place. This means it physically modifies the original array you called it on. While it does return a reference to the sorted array, it is the exact same array in memory.

javascript
const letters = ['c', 'a', 'b'];
const result = letters.sort();
console.log(letters === result);
Output
true

This mutation can introduce severe bugs if you sort an array that is being used elsewhere in your application, as you will accidentally scramble the data for other components. We can visualize this memory reference behavior:

letters result ['a', 'b', 'c'] Both variables point to the exact same mutated array in memory
sort() mutates in place and returns the same array, so the original variable and the 'result' variable point at one object — sorting through either is visible through both.

If you need to sort an array without destroying its original order, you should use the modern toSorted() method. It behaves identically to sort(), but returns a brand new copied array, leaving your original data completely untouched.

javascript
const nums = [3, 1, 2];
const sorted = nums.toSorted();
console.log(nums);
console.log(sorted);
Output
[ 3, 1, 2 ]
[ 1, 2, 3 ]

Check yourself

What does the sort() method do to the original array?

Reveal answer

It mutates (changes) the original array in place and returns it. — sort() sorts the elements of an array in place. This means the original array is modified. Use toSorted() if you want a new array instead.

How does sort() behave by default when sorting numbers?

Reveal answer

It converts them to strings and sorts them alphabetically. — By default, sort() converts elements to strings and compares their UTF-16 code unit values. This causes "10" to come before "2", making it sort alphabetically rather than numerically.

What should a compare function return to sort an array in ascending order?

Reveal answer

A number: negative if a < b, positive if a > b, and 0 if equal. — The compare function must return a number. If it returns a negative value, a comes before b. If positive, b comes before a.

Challenges

Challenge 1 +20 XP

Sort the array of objects by the `age` property in ascending order.

javascript
  • Test 1 — expects "Bob\n"
Need a hint? (−25% XP)

Access the age property on the `a` and `b` arguments in your compare function.

Show solution (0 XP)
const users = [{name: 'Alice', age: 30}, {name: 'Bob', age: 25}];
users.sort((a, b) => a.age - b.age);
console.log(users[0].name);

Challenge 2 +20 XP

Sort the array of scores in descending order (highest to lowest).

javascript
  • Test 1 — expects "[ 100, 92, 88, 50 ]\n"
Need a hint? (−25% XP)

Subtract a from b to sort descending.

Show solution (0 XP)
const scores = [88, 50, 100, 92];
scores.sort((a, b) => b - a);
console.log(scores);

🐞 Bug Hunt +25 XP

A developer wanted to display both the original order of the scores and the sorted order. But their code prints the sorted array twice! Fix the code so it correctly preserves the original array while creating a sorted copy.

This code runs. It just does the wrong thing. Read it, find the defect, fix it — the tests below decide when you are right.

javascript
  • Test 1 — expects "10\n"
Need a hint? (−25% XP)

`sort()` modifies the original array in place. To get a sorted *copy* without mutating the original, use `toSorted()` instead.

Show solution (0 XP)
const highScores = [10, 50, 20, 100];
const sortedScores = highScores.toSorted((a, b) => b - a);

console.log(highScores[0]);