JavaScript is what’s called an “untyped” language, so here, it assumes that the numbers are words, and tries to sort them alphabetically. Specifically, it tries to sort them alphabetically as a dictionary would in a left-to-right language like English. In this case, just as “apple” would come before “asterisk”, 100000 would come before 21.
(Some would argue that it’s more of a “weakly typed” language, I know, but I’m trying not to be pedantic here.)
Sorting them as actual numbers would require some extra explicit instructions and guides. Most typed languages, like C, aren’t like this.
is there a good reason for javascript to work like that? python also isn’t typed like C and it sorts integer lists in the “normal” way, so it seems avoidable. (i don’t really know what im talking about here. i’ve never used javascript and i’m not familiar with how typing works under the hood.)
Mainly because JavaScript was designed to work along side HTTP in a browser. Most of its input will be text, so defaulting common behavior to strings makes some sense.
That’s misleading at best and most likely just false, and it’s worrying it’s so upvoted.
There’s no historical record explaining why this was designed this way, but we can infer some things. HTTP is very unlikely a factor, XHR / AJAX has been added years after the .sort() function. Additionally, it doesn’t make sense in the context that other comparisons are not string-wise (sort()/quicksort is basically a series of comparisons).
The trouble with JS arrays is that they can contain any values - e.g. [false, undefined, 1567, 10, "Hello world", { x: 1 }]. How do you sort those? There must be one function to compare every combination of value, but how do you compare booleans and objects?
There’s no such function which would provide reasonable results. In that context, doing .toString() and then string-wise comparison/sorting doesn’t seem that crazy - every object has .toString(), it will compute something, and often it will work well enough.
There could be some additional smartness - if the array contains numbers only, it could choose to use a number-wise comparison function. But that would require a) extra implementation complexity (JS was famously designed in short time) and b) reduced performance - since JS runtime doesn’t know what type of values are present in the array, it would have to scan the whole array before starting the sort. But I guess the a) was the decisive factor in the beginning and backwards compatibility prevented improving the function later.
You are probably correct. I don’t know if it’s true, it’s probably more likely it was a way for it not to fail.
I said HTTP mainly because HTML is plaintext because of it. 1.0s main purpose was to manipulate the page. Of course Array objects weren’t added til 1.1, when netscape navigator 3.0 released, but it was still mostly 1.0 code. I felt like having everything be coercable to string made it easy for you to just assign it to the document. If you assigned the wrong thing it wouldn’t crash.
I originally thought there was a precursor to microsofts XMLHTTP in an earlier version due to the 1997 ECMAScript documentation specifically talking about using it both client and serverside to distribute computations, but it was far more static. So, I’m probably just wrong.
The hard part is sorting values of different types.
Python 2 had a order of built it types. Something like None < bool < numbers < strings. This means that you could sort anything like JavaScript and behaves fairly reasonably.
Python 3 takes the “safer” approach and comparisons of different types throw an exception. (You can override the comparison behavior for your own types and do something different).
JavaScript has conventionally been a very loosely typed language. So it almost certainly wouldn’t have chosen the exception throwing option. It does something similar to Python 2. But instead of just directly comparing the values of different types it converts them to strings first, then compares everything as a string. This is probably the most reasonable option. Otherwise you would have problems because 10 < "2" and "2" < 3 but 3 < 10. How can that work? You have no total ordering! So basically because the comparison operators convert to strings if either argument is a string the default sort comparator really doesn’t have a choice but to do convert to string. The other option would be to define a total order just for the sort function but that seems more confusing.
It’s also an incorrect alphabetical sort in many languages that use accented characters. For a correct sort you need to pass it something like the localeCompare function or Intl.Collator.
JavaScript is what’s called an “untyped” language, so here, it assumes that the numbers are words, and tries to sort them alphabetically. Specifically, it tries to sort them alphabetically as a dictionary would in a left-to-right language like English. In this case, just as “apple” would come before “asterisk”, 100000 would come before 21.
(Some would argue that it’s more of a “weakly typed” language, I know, but I’m trying not to be pedantic here.)
Sorting them as actual numbers would require some extra explicit instructions and guides. Most typed languages, like C, aren’t like this.
is there a good reason for javascript to work like that? python also isn’t typed like C and it sorts integer lists in the “normal” way, so it seems avoidable. (i don’t really know what im talking about here. i’ve never used javascript and i’m not familiar with how typing works under the hood.)
Mainly because JavaScript was designed to work along side HTTP in a browser. Most of its input will be text, so defaulting common behavior to strings makes some sense.
That’s misleading at best and most likely just false, and it’s worrying it’s so upvoted.
There’s no historical record explaining why this was designed this way, but we can infer some things. HTTP is very unlikely a factor, XHR / AJAX has been added years after the
.sort()
function. Additionally, it doesn’t make sense in the context that other comparisons are not string-wise (sort()/quicksort is basically a series of comparisons).The trouble with JS arrays is that they can contain any values - e.g.
[false, undefined, 1567, 10, "Hello world", { x: 1 }]
. How do you sort those? There must be one function to compare every combination of value, but how do you compare booleans and objects?There’s no such function which would provide reasonable results. In that context, doing
.toString()
and then string-wise comparison/sorting doesn’t seem that crazy - every object has.toString()
, it will compute something, and often it will work well enough.There could be some additional smartness - if the array contains numbers only, it could choose to use a number-wise comparison function. But that would require a) extra implementation complexity (JS was famously designed in short time) and b) reduced performance - since JS runtime doesn’t know what type of values are present in the array, it would have to scan the whole array before starting the sort. But I guess the a) was the decisive factor in the beginning and backwards compatibility prevented improving the function later.
You are probably correct. I don’t know if it’s true, it’s probably more likely it was a way for it not to fail.
I said HTTP mainly because HTML is plaintext because of it. 1.0s main purpose was to manipulate the page. Of course Array objects weren’t added til 1.1, when netscape navigator 3.0 released, but it was still mostly 1.0 code. I felt like having everything be coercable to string made it easy for you to just assign it to the document. If you assigned the wrong thing it wouldn’t crash.
I originally thought there was a precursor to microsofts XMLHTTP in an earlier version due to the 1997 ECMAScript documentation specifically talking about using it both client and serverside to distribute computations, but it was far more static. So, I’m probably just wrong.
thank you for the explanation, that does clarify things
The hard part is sorting values of different types.
Python 2 had a order of built it types. Something like None < bool < numbers < strings. This means that you could sort anything like JavaScript and behaves fairly reasonably.
Python 3 takes the “safer” approach and comparisons of different types throw an exception. (You can override the comparison behavior for your own types and do something different).
JavaScript has conventionally been a very loosely typed language. So it almost certainly wouldn’t have chosen the exception throwing option. It does something similar to Python 2. But instead of just directly comparing the values of different types it converts them to strings first, then compares everything as a string. This is probably the most reasonable option. Otherwise you would have problems because
10 < "2"
and"2" < 3
but3 < 10
. How can that work? You have no total ordering! So basically because the comparison operators convert to strings if either argument is a string the default sort comparator really doesn’t have a choice but to do convert to string. The other option would be to define a total order just for the sort function but that seems more confusing.It’s also an incorrect alphabetical sort in many languages that use accented characters. For a correct sort you need to pass it something like the localeCompare function or Intl.Collator.