Array.prototype.sort()

Sorts an array in place, comparing elements as strings unless a comparator function is supplied.

Signature
sort()
sort(compareFn)
  • Added in JavaScript ES1

Parameters

ParameterTypeDescription
$compareFnoptionalFunction= undefined (elements are compared as strings)A function that determines the order of the elements, called with (a, b). Return a negative value if a comes before b, a positive value if a comes after b, and zero or NaN if they are equal. Neither a nor b will ever be undefined.

Return value

ArrayThe reference to the original array, now sorted. Note that the array is sorted in place, and no copy is made.

Errors

Throws a TypeError when called on a frozen array, or when compareFn is provided but is neither undefined nor a callable function.

Changelog

  • PHP ES1Present on Array.prototype from the first edition of the language.
  • PHP ES2019The sort is required to be stable: elements that compare equal keep their original relative order.

sort() orders an array in place and returns a reference to that same array — not a copy. With no comparator, it converts every non-undefined element to a string and compares UTF-16 code units.

When to reach for it

Any time you need a defined order: table columns, leaderboards, alphabetised names, chronological events. Since ES2019 the sort is stable, so you can sort by a secondary key first and then by the primary key, and the secondary order survives within ties.

What trips people up

The default string comparison is the classic bug: [10, 9, 1, 80].sort() yields [1, 10, 80, 9] because "10" sorts before "9". Numbers always need (a, b) => a - b.

It mutates. Sorting a prop, a cached response, or a caller's argument reorders their data too — copy first with slice() or spread, or use toSorted().

A comparator must be consistent: returning a boolean (as in a > b) is a bug, since false coerces to 0 and means "equal". Non-ASCII text needs localeCompare, because raw code-unit order puts every accented letter after z. undefined values sort to the end and holes after them, without ever reaching the comparator.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Order a table of records by a numeric column such as price or score
  • Alphabetise names correctly in a language with accented characters
  • Apply a two-level sort by relying on stability, secondary key first
  • Sort a copy of a data set so the original order remains available

Frequently asked questions

Why does sort() put 10 before 9?

Without a comparator, sort() converts elements to strings and compares UTF-16 code units, so "10" precedes "9"; pass (a, b) => a - b to sort numerically.

Does sort() modify the original array?

Yes, sort() reorders the array in place and returns a reference to that same array; use toSorted(), or copy with slice() or spread first, to keep the original order.

Is JavaScript's sort stable?

Yes, since ES2019 the specification requires stability, so elements that compare equal keep their original relative order and multi-pass sorting works reliably.

More examples

Sorting objects by several keys

Because the sort is stable since ES2019, the name ordering established by the first pass is preserved inside each department. The output is eng/ada, eng/cy, ops/al, ops/bob.

Example · javascript
const rows = [
  { dept: "eng", name: "ada" },
  { dept: "ops", name: "bob" },
  { dept: "eng", name: "cy" },
  { dept: "ops", name: "al" },
];

rows.sort((a, b) => a.name.localeCompare(b.name)); // secondary first
rows.sort((a, b) => a.dept.localeCompare(b.dept)); // primary second

console.log(rows.map((r) => `${r.dept}/${r.name}`).join(", "));

Sorting without mutating the source

Spreading into a new array before sorting protects the original ordering. The second half shows the default behaviour: sort returns the very same array it mutated.

Example · javascript
const scores = [5, 1, 3];

const copy = [...scores].sort((a, b) => b - a);
console.log(copy);   // [5,3,1]
console.log(scores); // [5,1,3] — untouched

const inPlace = scores.sort((a, b) => b - a);
console.log(scores);            // [5,3,1] — source rewritten
console.log(inPlace === scores); // true — same reference

Comparators that misbehave

The boolean comparator never returns a negative number, so the engine is told elements are either equal or out of order and the result is unreliable. The last line shows undefined being placed at the end without any comparison.

Example · javascript
const nums = [3, 1, 2];

// Wrong: a boolean coerces to 0 or 1, never negative.
console.log([...nums].sort((a, b) => a > b));

// Right: a numeric difference.
console.log([...nums].sort((a, b) => a - b)); // [1,2,3]

// undefined and holes go last, comparator never sees them.
console.log(["b", undefined, "a"].sort()); // ['a','b',undefined]

Discussion

  • Be the first to comment on this lesson.