2016-12-11 91 views
4

我发现使用没有比较函数的排序会导致错误的答案,我不知道原因。Javascript Array.prototype.sort()错误,没有比较功能

var a = [823564440,115438165,784484492,74243042,114807987,137522503,441282327,16531729,823378840,143542612] 

a.sort() 
a.sort((a,b) => a-b) 

这两个应该在我的脑海中给出相同的结果,但他们没有。显然后者是正确的。

a.sort() 
[114807987, 115438165, 137522503, 143542612, 16531729, 441282327, 74243042, 784484492, 823378840, 823564440] 
a.sort((a, b) => a-b) 
[16531729, 74243042, 114807987, 115438165, 137522503, 143542612, 441282327, 784484492, 823378840, 823564440] 

有谁能告诉我背后的原因吗?

+4

从[documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort):*默认的排序顺序是根据字符串的Unicode代码点。* – Li357

+1

首先将项目比作字符串。 – zerkms

+0

字符串排序与数字排序。 –

回答

5

MDN documentation

sort()方法排序的阵列的代替元素并返回数组。排序不一定稳定。 默认的排序顺序是根据字符串Unicode代码点。(Emphasis mine)†

由于您没有提供函数,因此使用默认排序顺序。因此,这些元素按照字符串进行排序,而后者则根据数字值排序。

因此,1之前2,2之前3等无论数字的位数作为字符串比较的地方。 (请参见list of unicode characters;因为Unicode中的1是U + 0031,所以它在U + 0032之前,因此更小)。

在你的例子中,这意味着115438165之前74243042虽然后者是数学上较小。因为字符串被地方比较所以17比较不到,从而得到了结果。有关进一步阅读,请参阅lexicographical order


†这是通过规范。请参阅ECMAScript® 2015 Language Specification,第22.1.3.24.1节 - 运行时语义:SortCompare(x, y)。这里解释了如果没有通过排序功能,则比较xy(使用ToString找到)的字符串表示。

+1

谢谢!数值阵列这样做很奇怪。 –

+0

@xgwang这样做可能看起来很奇怪,但是(我相信)逻辑原因是因为数组可以容纳任何东西 - 不仅仅是数字。如果没有排序函数传递并且您有一个非数字对象数组会怎么样?它不是按数字排序,而是根据字符串表示进行排序。 – Li357