ECMAScript spec.
First of all, from the ECMASCript specification:
The elements of this array are sorted. The sort is not necessarily stable (that is, elements that compare equal do not necessarily remain in their original order). If comparefn is not undefined, it should be a function that accepts two arguments x and y and returns a negative value if x < y, zero if x = y, or a positive value if x > y.
And, if you take a look
The notation a <CF b means comparefn(a,b) < 0
; a =CF b means comparefn(a,b) = 0
(of either sign); and a >CF b means comparefn(a,b) > 0
.
If a =CF b, then b =CF a (symmetry)
That line from the specification means that if do compareFunction("a", "b")
and you get 0; you must get 0 when you do compareFunction("b", "a")
. You don’t. Because “0” signifies equivalence.
Because the comparison function isn’t consistent, the specification says that the sort order is “implementation-defined” according to the specification. You can’t know what it will sort to.
MDN docs
The MDN docs generally just interpret the ECMAScript specification and make it easier to understand.
- If compareFunction(a, b) is less than 0, sort a to an index lower than b, i.e. a comes first.
- If compareFunction(a, b) returns 0, leave a and b unchanged with respect to each other, but sorted with respect to all different elements. Note: the ECMAscript standard does not guarantee this behaviour, and thus not all browsers (e.g. Mozilla versions dating back to at least 2003) respect this.
- If compareFunction(a, b) is greater than 0, sort b to an index lower than a, i.e. b comes first.
My bold. So the sort function is supposed to return “0” only for equality, and while most browsers probably will leave the sort order unchanged, there is no guarantee
Real-world example
As stated above in the MDN docs, most browsers treat “0” as keep-same-order. However, they just do it because they feel like it. They’d still be running the JavaScript correctly if they returned to you [“bananas”], if I’m not mistaken.
In a code golf StackExchange question, we had to sort numbers based on whether they were even or odd. I tried to return false
and true
. However, somebody found a very long array [-5…20] which broke it! This was in Chrome.
I was so sure it worked. Anywho, if you’re just sorting numbers normally, you might be safe in modern browsers, but it’s a good practice that might make you compatible with a much wider variety of JavaScript engines — as MDN said, Firefox before 2003 did not guarantee “0” means “-1” — because it’s simply not in the specification.