Non-Mutating Array Sorting in JavaScript: An In-Depth Analysis of toSorted()

Nov 23, 2025 · Programming · 8 views · 7.8

Keywords: JavaScript | Array Sorting | Non-Mutating Methods | toSorted | Functional Programming

Abstract: This article provides a comprehensive exploration of non-mutating array sorting methods in JavaScript, with a primary focus on the ES2023 toSorted() method. Through comparative analysis with the traditional mutating sort() method, it details the working principles, application scenarios, and performance characteristics of toSorted(), while also covering alternative implementations including spread operator and slice() method applications. The article includes complete code examples and practical use case analyses to help developers deeply understand functional programming paradigms in JavaScript array operations.

Introduction

Array sorting is a common requirement in JavaScript development. While the traditional Array.prototype.sort() method is powerful, its mutating nature often introduces unexpected side effects to programs. This article aims to provide an in-depth exploration of implementing non-mutating array sorting operations, with particular focus on the toSorted() method introduced in the ES2023 standard.

Limitations of Traditional sort() Method

JavaScript's built-in sort() method directly modifies the original array, which can lead to hard-to-track bugs in certain scenarios. For example:

const originalArray = [3, 1, 4, 1, 5, 9, 2, 6];
const sortedArray = originalArray.sort();
console.log(originalArray); // Output: [1, 1, 2, 3, 4, 5, 6, 9]
console.log(sortedArray);   // Output: [1, 1, 2, 3, 4, 5, 6, 9]

As demonstrated in the above example, the original array originalArray has been modified, violating the principle of immutable data in functional programming.

Detailed Analysis of ES2023 toSorted() Method

toSorted() is a copying method of Array instances that returns a new sorted array without modifying the original array. Its basic syntax is as follows:

array.toSorted([compareFunction])

Practical application example:

const numbers = [2, 1, 3];
const sortedNumbers = numbers.toSorted();

console.log(numbers);        // Output: [2, 1, 3]
console.log(sortedNumbers);  // Output: [1, 2, 3]

For sorting complex data types:

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

const sortedByAge = users.toSorted((a, b) => a.age - b.age);
console.log(users);        // Original array remains unchanged
console.log(sortedByAge);  // New array sorted by age

Compatibility Solutions

Prior to ES2023, developers needed to implement non-mutating sorting through alternative approaches. Here are several commonly used compatibility solutions:

Spread Operator Approach

Using ES6 spread operator to create array copies:

function immutableSort(arr) {
  return [...arr].sort();
}

const arr = [2, 3, 7, 5, 3, 7, 1, 3, 4];
const sorted = immutableSort(arr);
console.log(arr);    // Output: [2, 3, 7, 5, 3, 7, 1, 3, 4]
console.log(sorted); // Output: [1, 2, 3, 3, 3, 4, 5, 7, 7]

slice() Method

Using slice() method to create shallow copies:

function immutableSort(arr) {
  return arr.slice().sort();
}

// Or using concat() method
function immutableSortConcat(arr) {
  return arr.concat().sort();
}

Performance Analysis and Best Practices

The toSorted() method performs comparably to traditional methods combined with copy operations but offers better semantic clarity. When choosing sorting methods, consider the following factors:

Practical Application Scenarios

Non-mutating sorting is particularly useful in the following scenarios:

  1. React State Management: Maintaining immutable state in functional components
  2. Data Pipelines: Preserving original data integrity in data processing chains
  3. Debugging and Testing: Facilitating data change tracking and snapshot testing

Conclusion

The introduction of the toSorted() method represents a significant advancement in JavaScript's support for functional programming. It not only provides safer array operations but also enhances code readability and maintainability. For modern JavaScript development, it is recommended to prioritize toSorted() in supported environments, with spread operator or slice() as fallback solutions in unsupported environments.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.