Array.prototype.sort()
BaselineWidely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
Thesort()
method ofArray
instances sorts the elements of an arrayin place and returns the reference to the same array, now sorted. The default sort order is ascending, built upon converting the elements into strings, then comparing their sequences of UTF-16 code unit values.
The time and space complexity of the sort cannot be guaranteed as it depends on theimplementation.
To sort the elements in an array without mutating the original array, usetoSorted()
.
Try it
const months = ["March", "Jan", "Feb", "Dec"];months.sort();console.log(months);// Expected output: Array ["Dec", "Feb", "Jan", "March"]const array1 = [1, 30, 4, 21, 100000];array1.sort();console.log(array1);// Expected output: Array [1, 100000, 21, 30, 4]
Syntax
sort()sort(compareFn)
Parameters
compareFn
OptionalA function that determines the order of the elements. The function is called with the following arguments:
a
The first element for comparison. Will never be
undefined
.b
The second element for comparison. Will never be
undefined
.
It should return a number where:
- A negative value indicates that
a
should come beforeb
. - A positive value indicates that
a
should come afterb
. - Zero or
NaN
indicates thata
andb
are considered equal.
To memorize this, remember that
(a, b) => a - b
sorts numbers in ascending order.If omitted, the array elements are converted to strings, then sorted according to each character's Unicode code point value.
Return value
The reference to the original array, now sorted. Note that the array is sortedin place, and no copy is made.
Description
IfcompareFn
is not supplied, all non-undefined
arrayelements are sorted by converting them to strings and comparing strings in UTF-16 codeunits order. For example, "banana" comes before "cherry". In a numeric sort, 9 comesbefore 80, but because numbers are converted to strings, "80" comes before "9" in theUnicode order. Allundefined
elements are sorted to the end of the array.
Thesort()
method preserves empty slots. If the source array issparse, the empty slots are moved to the end of the array, and always come after all theundefined
.
Note:In UTF-16, Unicode characters above\uFFFF
areencoded as two surrogate code units, of the range\uD800
-\uDFFF
. The value of each code unit is takenseparately into account for the comparison. Thus the character formed by the surrogatepair\uD855\uDE51
will be sorted before the character\uFF3A
.
IfcompareFn
is supplied, all non-undefined
arrayelements are sorted according to the return value of the compare function (allundefined
elements are sorted to the end of the array, with no call tocompareFn
).
compareFn(a, b) return value | sort order |
---|---|
> 0 | sorta afterb , e.g.,[b, a] |
< 0 | sorta beforeb , e.g.,[a, b] |
=== 0 | keep original order ofa andb |
So, the compare function has the following form:
function compareFn(a, b) { if (a is less than b by some ordering criterion) { return -1; } else if (a is greater than b by the ordering criterion) { return 1; } // a must be equal to b return 0;}
More formally, the comparator is expected to have the following properties, in order to ensure proper sort behavior:
- Pure: The comparator does not mutate the objects being compared or any external state. (This is important because there's no guaranteewhen andhow the comparator will be called, so any particular call should not produce visible effects to the outside.)
- Stable: The comparator returns the same result with the same pair of input.
- Reflexive:
compareFn(a, a) === 0
. - Anti-symmetric:
compareFn(a, b)
andcompareFn(b, a)
must both be0
or have opposite signs. - Transitive: If
compareFn(a, b)
andcompareFn(b, c)
are both positive, zero, or negative, thencompareFn(a, c)
has the same positivity as the previous two.
A comparator conforming to the constraints above will always be able to return all of1
,0
, and-1
, or consistently return0
. For example, if a comparator only returns1
and0
, or only returns0
and-1
, it will not be able to sort reliably becauseanti-symmetry is broken. A comparator that always returns0
will cause the array to not be changed at all, but is reliable nonetheless.
The default lexicographic comparator satisfies all constraints above.
To compare numbers instead of strings, the compare function can subtractb
froma
. The following function will sort the array in ascending order (ifit doesn't containNaN
):
function compareNumbers(a, b) { return a - b;}
Thesort()
method isgeneric. It only expects thethis
value to have alength
property and integer-keyed properties. Although strings are also array-like, this method is not suitable to be applied on them, as strings are immutable.
Examples
Creating, displaying, and sorting an array
The following example creates four arrays and displays the original array, then thesorted arrays. The numeric arrays are sorted without a compare function, then sortedusing one.
const stringArray = ["Blue", "Humpback", "Beluga"];const numberArray = [40, 1, 5, 200];const numericStringArray = ["80", "9", "700"];const mixedNumericArray = ["80", "9", "700", 40, 1, 5, 200];function compareNumbers(a, b) { return a - b;}stringArray.join(); // 'Blue,Humpback,Beluga'stringArray.sort(); // ['Beluga', 'Blue', 'Humpback']numberArray.join(); // '40,1,5,200'numberArray.sort(); // [1, 200, 40, 5]numberArray.sort(compareNumbers); // [1, 5, 40, 200]numericStringArray.join(); // '80,9,700'numericStringArray.sort(); // ['700', '80', '9']numericStringArray.sort(compareNumbers); // ['9', '80', '700']mixedNumericArray.join(); // '80,9,700,40,1,5,200'mixedNumericArray.sort(); // [1, 200, 40, 5, '700', '80', '9']mixedNumericArray.sort(compareNumbers); // [1, 5, '9', 40, '80', 200, '700']
Sorting array of objects
Arrays of objects can be sorted by comparing the value of one of their properties.
const items = [ { name: "Edward", value: 21 }, { name: "Sharpe", value: 37 }, { name: "And", value: 45 }, { name: "The", value: -12 }, { name: "Magnetic", value: 13 }, { name: "Zeros", value: 37 },];// sort by valueitems.sort((a, b) => a.value - b.value);// sort by nameitems.sort((a, b) => { const nameA = a.name.toUpperCase(); // ignore upper and lowercase const nameB = b.name.toUpperCase(); // ignore upper and lowercase if (nameA < nameB) { return -1; } if (nameA > nameB) { return 1; } // names must be equal return 0;});
Sorting non-ASCII characters
For sorting strings with non-ASCII characters, i.e., strings with accented characters(e, é, è, a, ä, etc.), strings from languages other than English, useString.prototype.localeCompare()
. This function can compare those characters so theyappear in the right order.
const items = ["réservé", "premier", "communiqué", "café", "adieu", "éclair"];items.sort((a, b) => a.localeCompare(b));// items is ['adieu', 'café', 'communiqué', 'éclair', 'premier', 'réservé']
Sorting with map
ThecompareFn
can be invoked multiple times per element within thearray. Depending on thecompareFn
's nature, this may yield a highoverhead. The more work acompareFn
does and the more elements thereare to sort, it may be more efficient to usemap()
forsorting. The idea is to traverse the array once to extract the actual values used forsorting into a temporary array, sort the temporary array, and then traverse thetemporary array to achieve the right order.
// the array to be sortedconst data = ["delta", "alpha", "charlie", "bravo"];// temporary array holds objects with position and sort-valueconst mapped = data.map((v, i) => ({ i, value: someSlowOperation(v) }));// sorting the mapped array containing the reduced valuesmapped.sort((a, b) => { if (a.value > b.value) { return 1; } if (a.value < b.value) { return -1; } return 0;});const result = mapped.map((v) => data[v.i]);
There is an open source library available calledmapsort which applies this approach.
sort() returns the reference to the same array
Thesort()
method returns a reference to the original array, so mutating the returned array will mutate the original array as well.
const numbers = [3, 1, 4, 1, 5];const sorted = numbers.sort((a, b) => a - b);// numbers and sorted are both [1, 1, 3, 4, 5]sorted[0] = 10;console.log(numbers[0]); // 10
In case you wantsort()
to not mutate the original array, but return ashallow-copied array like other array methods (e.g.,map()
) do, use thetoSorted()
method. Alternatively, you can do a shallow copy before callingsort()
, using thespread syntax orArray.from()
.
const numbers = [3, 1, 4, 1, 5];// [...numbers] creates a shallow copy, so sort() does not mutate the originalconst sorted = [...numbers].sort((a, b) => a - b);sorted[0] = 10;console.log(numbers[0]); // 3
Sort stability
Since version 10 (or ECMAScript 2019), the specification dictates thatArray.prototype.sort
is stable.
For example, say you had a list of students alongside their grades. Note that the list of students is already pre-sorted by name in alphabetical order:
const students = [ { name: "Alex", grade: 15 }, { name: "Devlin", grade: 15 }, { name: "Eagle", grade: 13 }, { name: "Sam", grade: 14 },];
After sorting this array bygrade
in ascending order:
students.sort((firstItem, secondItem) => firstItem.grade - secondItem.grade);
Thestudents
variable will then have the following value:
[ { name: "Eagle", grade: 13 }, { name: "Sam", grade: 14 }, { name: "Alex", grade: 15 }, // original maintained for similar grade (stable sorting) { name: "Devlin", grade: 15 }, // original maintained for similar grade (stable sorting)];
It's important to note that students that have the same grade (for example, Alex and Devlin), will remain in the same order as before calling the sort. This is what a stable sorting algorithm guarantees.
Before version 10 (or ECMAScript 2019), sort stability was not guaranteed, meaning that you could end up with the following:
[ { name: "Eagle", grade: 13 }, { name: "Sam", grade: 14 }, { name: "Devlin", grade: 15 }, // original order not maintained { name: "Alex", grade: 15 }, // original order not maintained];
Sorting with non-well-formed comparator
If a comparing function does not satisfy all of purity, stability, reflexivity, anti-symmetry, and transitivity rules, as explained in thedescription, the program's behavior is not well-defined.
For example, consider this code:
const arr = [3, 1, 4, 1, 5, 9];const compareFn = (a, b) => (a > b ? 1 : 0);arr.sort(compareFn);
ThecompareFn
function here is not well-formed, because it does not satisfy anti-symmetry: ifa > b
, it returns1
; but by swappinga
andb
, it returns0
instead of a negative value. Therefore, the resulting array will be different across engines. For example, V8 (used by Chrome, Node.js, etc.) and JavaScriptCore (used by Safari) would not sort the array at all and return[3, 1, 4, 1, 5, 9]
, while SpiderMonkey (used by Firefox) will return the array sorted ascendingly, as[1, 1, 3, 4, 5, 9]
.
However, if thecompareFn
function is changed slightly so that it returns-1
or0
:
const arr = [3, 1, 4, 1, 5, 9];const compareFn = (a, b) => (a > b ? -1 : 0);arr.sort(compareFn);
Then V8 and JavaScriptCore sorts it descendingly, as[9, 5, 4, 3, 1, 1]
, while SpiderMonkey returns it as-is:[3, 1, 4, 1, 5, 9]
.
Due to this implementation inconsistency, you are always advised to make your comparator well-formed by following the five constraints.
Using sort() on sparse arrays
Empty slots are moved to the end of the array.
console.log(["a", "c", , "b"].sort()); // ['a', 'b', 'c', empty]console.log([, undefined, "a", "b"].sort()); // ["a", "b", undefined, empty]
Calling sort() on non-array objects
Thesort()
method reads thelength
property ofthis
. It then collects all existing integer-keyed properties in the range of0
tolength - 1
, sorts them, and writes them back. If there are missing properties in the range, the corresponding trailing properties aredeleted, as if the non-existent properties are sorted towards the end.
const arrayLike = { length: 3, unrelated: "foo", 0: 5, 2: 4,};console.log(Array.prototype.sort.call(arrayLike));// { '0': 4, '1': 5, length: 3, unrelated: 'foo' }
Specifications
Specification |
---|
ECMAScript® 2026 Language Specification # sec-array.prototype.sort |
Browser compatibility
See also
- Polyfill of
Array.prototype.sort
with modern behavior like stable sort incore-js
- Indexed collections guide
Array
Array.prototype.reverse()
Array.prototype.toSorted()
String.prototype.localeCompare()
TypedArray.prototype.sort()
- Getting things sorted in V8 on v8.dev (2018)
- Stable
Array.prototype.sort
on v8.dev (2019) Array.prototype.sort
stability by Mathias Bynens