Last modified: Aug 03, 2026

Sort JS Array of Objects by Property

Sorting an array of objects is a common task in JavaScript. You often need to arrange data by a specific property, like name, age, or date. The built-in sort() method makes this easy, but it has a few quirks you must understand.

This guide will show you exactly how to sort objects by a property. We'll cover strings, numbers, dates, and nested properties. You'll also learn how to avoid common bugs and write clean, readable code.

The Basics of sort()

The sort() method sorts the elements of an array in place. This means it changes the original array. It also returns the sorted array.

By default, sort() converts elements to strings and compares their UTF-16 code units. This works for strings but fails for numbers. For example, 10 comes before 2 because "10" is less than "2" alphabetically.

To sort correctly, you must pass a compare function. This function defines the sort order and returns a number.


// Default sort (bad for numbers)
const nums = [10, 2, 5, 1];
nums.sort();
console.log(nums); // Output: [1, 10, 2, 5] (wrong order)

[1, 10, 2, 5]

Sorting by a Numeric Property

To sort objects by a numeric property, your compare function should subtract one property from the other. This gives a positive, negative, or zero result.

Here's an example with an array of user objects. We'll sort them by age, from youngest to oldest.


const users = [
  { name: "Alice", age: 30 },
  { name: "Bob", age: 25 },
  { name: "Charlie", age: 35 }
];

// Sort by age (ascending)
users.sort((a, b) => a.age - b.age);

console.log(users);

[
  { name: "Bob", age: 25 },
  { name: "Alice", age: 30 },
  { name: "Charlie", age: 35 }
]

The compare function (a, b) => a.age - b.age works perfectly. If the result is negative, a comes first. If positive, b comes first. If zero, their order stays the same.

For descending order, just reverse the subtraction: b.age - a.age.

Sorting by a String Property

Strings are sorted using the localeCompare() method. This method is powerful because it handles uppercase, lowercase, and special characters correctly.

Let's sort our users by name alphabetically. Using localeCompare() is the recommended way for strings.


const users = [
  { name: "alice", age: 30 },
  { name: "Bob", age: 25 },
  { name: "charlie", age: 35 }
];

// Sort by name (ascending, case-insensitive)
users.sort((a, b) => a.name.localeCompare(b.name));

console.log(users);

[
  { name: "alice", age: 30 },
  { name: "Bob", age: 25 },
  { name: "charlie", age: 35 }
]

Notice that localeCompare() automatically handles case sensitivity. It sorts "alice" before "Bob" because it compares characters based on locale rules. This is much safer than using simple comparison operators like < or >.

Sorting by a Date Property

Dates are often stored as strings or timestamps. If you have date strings in ISO format (YYYY-MM-DD), you can sort them directly as strings. But for full control, convert them to Date objects first.

Here's an example with event objects. We'll sort by the date property, which is a string.


const events = [
  { title: "Meeting", date: "2025-03-10" },
  { title: "Party", date: "2025-01-15" },
  { title: "Workshop", date: "2025-06-20" }
];

// Sort by date (ascending)
events.sort((a, b) => new Date(a.date) - new Date(b.date));

console.log(events);

[
  { title: "Party", date: "2025-01-15" },
  { title: "Meeting", date: "2025-03-10" },
  { title: "Workshop", date: "2025-06-20" }
]

Using new Date() converts the string to a timestamp. Subtracting timestamps gives a numeric result, so sorting works correctly. This method is reliable for standard date formats.

Sorting by Nested Properties

Sometimes your objects have nested structures. For example, a user might have an address object with a city property. You can sort by accessing the nested property directly.

Here's an example with a profile object inside each user. We'll sort by the city name.


const users = [
  { name: "Alice", profile: { city: "New York" } },
  { name: "Bob", profile: { city: "Los Angeles" } },
  { name: "Charlie", profile: { city: "Chicago" } }
];

// Sort by city (ascending)
users.sort((a, b) => a.profile.city.localeCompare(b.profile.city));

console.log(users);

[
  { name: "Charlie", profile: { city: "Chicago" } },
  { name: "Bob", profile: { city: "Los Angeles" } },
  { name: "Alice", profile: { city: "New York" } }
]

You can chain property access like a.profile.city. This works for any depth, but be careful with null or undefined values. If a property is missing, your code will throw an error.

Handling Null and Undefined Values

Real-world data often has missing properties. If you try to sort by a property that doesn't exist, you'll get a TypeError. To avoid this, you need to handle missing values gracefully.

One approach is to check if the property exists before sorting. You can assign a default value, like an empty string or zero.


const users = [
  { name: "Alice", age: 30 },
  { name: "Bob" }, // no age property
  { name: "Charlie", age: 35 }
];

// Sort by age, treating missing as 0
users.sort((a, b) => (a.age || 0) - (b.age || 0));

console.log(users);

[
  { name: "Bob", age: undefined }, // treated as 0
  { name: "Alice", age: 30 },
  { name: "Charlie", age: 35 }
]

Using || 0 replaces undefined with 0. This keeps the sort stable and avoids errors. For strings, use || "".

Sorting with Multiple Criteria

Sometimes you need to sort by multiple properties. For example, sort by age first, then by name if ages are equal. You can achieve this with a chained compare function.

Here's an example with a priority system. If ages are equal, we sort by name.


const users = [
  { name: "Alice", age: 30 },
  { name: "Bob", age: 25 },
  { name: "Charlie", age: 25 },
  { name: "David", age: 30 }
];

// Sort by age, then by name
users.sort((a, b) => {
  if (a.age !== b.age) {
    return a.age - b.age; // primary sort
  }
  return a.name.localeCompare(b.name); // secondary sort
});

console.log(users);

[
  { name: "Bob", age: 25 },
  { name: "Charlie", age: 25 },
  { name: "Alice", age: 30 },
  { name: "David", age: 30 }
]

This pattern is very powerful. You can add as many conditions as you need. Just remember to keep the logic clear and readable.

Performance and Best Practices

The sort() method is efficient, but you can optimize it. If you're sorting a large array, avoid doing heavy computations inside the compare function. For example, don't call new Date() repeatedly if you can precompute timestamps.

Another best practice is to not mutate the original array unless you need to. Use the spread operator to create a copy first.


const users = [
  { name: "Alice", age: 30 },
  { name: "Bob", age: 25 }
];

// Create a copy, then sort
const sortedUsers = [...users].sort((a, b) => a.age - b.age);

console.log(sortedUsers); // Sorted
console.log(users); // Original unchanged

[
  { name: "Bob", age: 25 },
  { name: "Alice", age: 30 }
]

This is especially important in React or state management, where you shouldn't modify state directly. It also makes your code more predictable.

If you're working with large datasets, consider using a library like Lodash. But for most cases, the native sort() is more than enough.

Common Pitfalls and Fixes

Here are the most common mistakes developers make when sorting objects. Being aware of them will save you debugging time.

1. Forgetting the compare function: This leads to incorrect numeric sorts. Always pass a function for numbers.

2. Using < and > for strings: This compares character codes, not locale order. Use localeCompare() instead.

3. Mutating the original array: If you don't want to change the original, use a copy.

4. Ignoring case sensitivity:localeCompare() handles this, but simple comparisons don't.

Here's a quick fix for a common bug with case-insensitive string sorting.


// Wrong: case-sensitive
users.sort((a, b) => a.name > b.name ? 1 : -1);

// Correct: case-insensitive
users.sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase()));

Always test with mixed case data to ensure your sort works as expected.

Real-World Example

Let's combine everything into a practical example. We have a list of products with price, rating, and name. We'll sort by price, then by rating.


const products = [
  { name: "Laptop", price: 1200, rating: 4.5 },
  { name: "Mouse", price: 25, rating: 4.8 },
  { name: "Keyboard", price: 80, rating: 4.2 },
  { name: "Monitor", price: 300, rating: 4.6 }
];

// Sort by price ascending, then rating descending
products.sort((a, b) => {
  if (a.price !== b.price) {
    return a.price - b.price;
  }
  return b.rating - a.rating; // higher rating first
});

console.log(products);

[
  { name: "Mouse", price: 25, rating: 4.8 },
  { name: "Keyboard", price: 80, rating: 4.2 },
  { name: "Monitor", price: 300, rating: 4.6 },
  { name: "Laptop", price: 1200, rating: 4.5 }
]

This pattern is common in e-commerce applications. You can easily adapt it for any data structure.

Further Reading

If you want to deepen your understanding of arrays, check out our guide on JavaScript Array Methods. It covers all built-in methods in detail.

You might also find our article on JavaScript Array of Objects helpful for more complex data manipulation.

For advanced sorting scenarios, like shuffling, see How to Shuffle a JavaScript Array Randomly.

Conclusion

Sorting an array of objects by property is straightforward with the sort() method. The key is to use a proper compare function. For numbers, subtract the properties. For strings, use localeCompare(). For dates, convert to timestamps.

Always handle missing values and consider using a copy to avoid mutating the original array. With these techniques, you can sort any data structure confidently.

Practice with your own data to get comfortable. The more you use sort(), the more natural it becomes. Happy coding!