Hello! Welcome back to our series on mastering modern JavaScript.
In the last lesson, we focused on locating data within arrays using find(), findIndex(), and includes(). These are essential skills for checking for the existence of items or retrieving them for further use.
Today, we're moving from finding to ordering. Once you have a collection of data, such as a list of products, users, or articles, you'll almost certainly need to present it in a sorted order—by price, by name, by date, and so on. This is where JavaScript's powerful sort() method comes in.
This lesson will teach you how to use sort() with custom comparator functions to order arrays of objects based on their properties. This is a fundamental skill for building dynamic applications, especially for features like the e-commerce catalog you're interested in building.
1. The Default sort() and Its Quirks
At first glance, sort() seems simple. But it has a crucial default behavior that can lead to unexpected results, especially with numbers.
Let's say we have an array of numbers: [100, 5, 40, 2]. If you simply call numbers.sort(), what do you think the output will be? It's not [2, 5, 40, 100]. Instead, you'll get [100, 2, 40, 5]. Why?
The following video explains this behavior perfectly. By default, sort() converts elements to strings and compares them based on their character codes.
JavaScript Comparator Function | Sorting Explained!
Watch the first part of the video 'JavaScript Comparator Function | Sorting Explained!' by The Code Creative to understand why the default sort() method can be problematic for numbers.
Watch from the beginning to 03:24. The key takeaway is that sort() converts elements to strings before comparing them, which is why '100' comes before '2'.
This default behavior makes it clear that for anything other than simple alphabetical sorting of strings, we need to provide our own sorting logic.
2. The Comparator Function: Taking Control of sort()
To tell sort() how to order elements, we pass it a special function called a comparator (or "compare function"). This function takes two arguments, conventionally named a and b, which represent two elements from the array being compared.
The comparator's job is to return a number that dictates the sort order:
- Negative Number (
< 0):ashould come beforeb. - Positive Number (
> 0):bshould come beforea. - Zero (
0):aandbare considered equal; their relative order is maintained.

For sorting numbers, this logic can be simplified into a very elegant pattern: (a, b) => a - b.
- If
a - bis negative,ais smaller and comes first. - If
a - bis positive,ais larger and comes second. - If
a - bis zero, they are equal.
This next clip from the same video demonstrates this concept beautifully.
JavaScript Comparator Function | Sorting Explained!
This section explains the comparator function in detail, including the meaning of its return values and the a - b shortcut for sorting numbers.
Watch from 03:24 to 09:25. Pay close attention to how the a - b and b - a patterns create ascending and descending sort orders, respectively.
3. Sorting Arrays of Objects
Now we get to the core of today's lesson. The same principle applies to sorting arrays of objects. Instead of comparing a and b directly, we compare one of their properties, like a.price and b.price.
Let's imagine you have a list of products for your e-commerce site.
const products = [
{ name: 'Laptop', price: 1200 },
{ name: 'Mouse', price: 25 },
{ name: 'Keyboard', price: 75 },
{ name: 'Monitor', price: 300 }
];
To sort these by price in ascending order, we use the a - b pattern on the price property:
// Sort by price (ascending)
products.sort((a, b) => a.price - b.price);
console.log(products);
/* Output:
[
{ name: 'Mouse', price: 25 },
{ name: 'Keyboard', price: 75 },
{ name: 'Monitor', price: 300 },
{ name: 'Laptop', price: 1200 }
]
*/
To sort in descending order, you just flip the operands:
// Sort by price (descending)
products.sort((a, b) => b.price - a.price);
This next video provides another quick and clear demonstration of this exact technique.
Learn JavaScript SORTING in 6 minutes! 🗃
The video 'Learn JavaScript SORTING in 6 minutes!' from Bro Code offers a very fast-paced, practical look at sorting objects by numeric and string properties.
Watch from 02:20 to 06:24. Notice the pattern for sorting by a number (a.age - b.age) and the different pattern required for sorting by a string (a.name.localeCompare(b.name)).
Sorting by String Properties
As the video highlighted, you can't subtract strings. For sorting by properties like name or category, we use the built-in string method localeCompare().
a.name.localeCompare(b.name) automatically returns the correct negative, positive, or zero value needed by sort().
// Sort by name (alphabetical, A-Z)
products.sort((a, b) => a.name.localeCompare(b.name));
console.log(products);
/* Output:
[
{ name: 'Keyboard', price: 75 },
{ name: 'Laptop', price: 1200 },
{ name: 'Monitor', price: 300 },
{ name: 'Mouse', price: 25 }
]
*/
4. An Important Detail: Sort Stability and Multi-level Sorting
What happens if you sort by a property where multiple items have the same value? For example, sorting products by price when several products cost $25. This is where sort stability becomes relevant. Modern JavaScript engines guarantee a "stable" sort, meaning that if two elements are considered equal by the comparator, their original relative order is preserved.
This concept is crucial for multi-level sorting. For instance, you might want to sort products by category first, and then by price within each category. The following article demonstrates this powerful technique.
How to sort an array of objects by multiple properties
This article, 'How to sort an array of objects by multiple properties in JavaScript', shows a practical, real-world pattern for implementing a secondary sort key.
Read the section titled 'Sorting objects by multiple properties'. Focus on the logic inside the comparator function: it first checks the primary sort key (age). Only if the ages are equal does it proceed to compare the secondary key (name).
Let's adapt that logic to an e-commerce example. We want to sort by category, then by price.
const items = [
{ name: 'Mouse', price: 25, category: 'Electronics' },
{ name: 'T-Shirt', price: 20, category: 'Apparel' },
{ name: 'Keyboard', price: 75, category: 'Electronics' },
{ name: 'Jeans', price: 50, category: 'Apparel' },
];
items.sort((a, b) => {
// 1. Primary sort: by category name
const categoryComparison = a.category.localeCompare(b.category);
// If categories are different, sort by category
if (categoryComparison !== 0) {
return categoryComparison;
}
// 2. Secondary sort: if categories are the same, sort by price
return a.price - b.price;
});
console.log(items);
/* Output:
[
{ name: 'T-Shirt', price: 20, category: 'Apparel' },
{ name: 'Jeans', price: 50, category: 'Apparel' },
{ name: 'Mouse', price: 25, category: 'Electronics' },
{ name: 'Keyboard', price: 75, category: 'Electronics' }
]
*/
This pattern is extremely useful and common in data-driven applications.
A Note on sort(): Like some other array methods, sort() modifies or mutates the original array. If you need to preserve the original, you should create a copy first, for example, using the spread syntax: [...myArray].sort(...).
5. Practice Exercise
Let's put this all together. Here is an array of product objects.
const productCatalog = [
{ id: 1, name: "Ergonomic Chair", category: "Office", price: 250 },
{ id: 2, name: "Wireless Mouse", category: "Electronics", price: 45 },
{ id: 3, name: "Standing Desk", category: "Office", price: 400 },
{ id: 4, name: "Bluetooth Keyboard", category: "Electronics", price: 80 },
{ id: 5, name: "Desk Lamp", category: "Office", price: 45 },
];
Your Tasks:
- Write the code to sort
productCatalogby price, from most expensive to least expensive. - Write the code to sort the original
productCatalogby name alphabetically (A-Z). - Challenge: Write the code to sort
productCatalogfirst by category (alphabetically), and then within each category, by price from highest to lowest.
Take your time to work through the tasks. When you're ready, check your answers below.
Click to see the solution
const productCatalog = [
{ id: 1, name: "Ergonomic Chair", category: "Office", price: 250 },
{ id: 2, name: "Wireless Mouse", category: "Electronics", price: 45 },
{ id: 3, name: "Standing Desk", category: "Office", price: 400 },
{ id: 4, name: "Bluetooth Keyboard", category: "Electronics", price: 80 },
{ id: 5, name: "Desk Lamp", category: "Office", price: 45 },
];
// Task 1 Solution: Sort by price, descending
productCatalog.sort((a, b) => b.price - a.price);
console.log('Sorted by price descending:', productCatalog);
/* Expected: Standing Desk, Ergonomic Chair, Bluetooth Keyboard, ... */
// Task 2 Solution: Sort by name, ascending
productCatalog.sort((a, b) => a.name.localeCompare(b.name));
console.log('Sorted by name ascending:', productCatalog);
/* Expected: Bluetooth Keyboard, Desk Lamp, Ergonomic Chair, ... */
// Task 3 Solution: Sort by category, then by price descending
productCatalog.sort((a, b) => {
// Primary sort: category
const categoryComparison = a.category.localeCompare(b.category);
if (categoryComparison !== 0) {
return categoryComparison;
}
// Secondary sort: price descending
return b.price - a.price;
});
console.log('Sorted by category and price:', productCatalog);
/* Expected:
[
{ id: 4, ... category: "Electronics", price: 80 },
{ id: 2, ... category: "Electronics", price: 45 },
{ id: 3, ... category: "Office", price: 400 },
{ id: 1, ... category: "Office", price: 250 },
{ id: 5, ... category: "Office", price: 45 }
]
*/
Conclusion
Excellent work today. You've learned how to take full control of array sorting, a skill you'll use constantly when managing data.
Key Takeaways:
- JavaScript's default
sort()treats elements as strings, which is unsuitable for numerical sorting. - You can provide a custom comparator function to define your own sorting logic.
- For ascending numeric sort on an object property, use
(a, b) => a.property - b.property. - For alphabetical sort, use
(a, b) => a.property.localeCompare(b.property). - You can implement multi-level sorting by nesting your comparison logic inside the comparator function.
- Remember that
sort()modifies the array in-place.
In our next lesson, we will explore two more crucial array methods: splice() and slice(). This will be an important lesson because it highlights the difference between methods that mutate the original array (like sort() and splice()) and those that create a new copy (slice()). Understanding this distinction is vital for writing predictable and bug-free code.