Array.prototype.sort()
sort() 方法就地对数组的元素进行排序,并返回对相同数组的引用。默认排序是将元素转换为字符串,然后按照它们的 UTF-16 码元值升序排序。
由于它取决于具体实现,因此无法保证排序的时间和空间复杂度。
尝试一下
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]
语法
JSCopy to Clipboard
sort()
sort(compareFn)
参数
-
compareFn
可选定义排序顺序的函数。返回值应该是一个数字,其正负性表示两个元素的相对顺序。该函数使用以下参数调用:
a
第一个用于比较的元素。不会是undefined
。b
第二个用于比较的元素。不会是undefined
。如果省略该函数,数组元素会被转换为字符串,然后根据每个字符的 Unicode 码位值进行排序。
返回值
经过排序的原始数组的引用。注意数组是就地排序的,不会进行复制。
描述
如果没有提供 compareFn
,所有非 undefined
的数组元素都会被转换为字符串,并按照 UTF-16 码元顺序比较字符串进行排序。例如“banana”会被排列到“cherry”之前。在数值排序中,9 出现在 80 之前,但因为数字会被转换为字符串,在 Unicode 顺序中“80”排在“9”之前。所有的 undefined
元素都会被排序到数组的末尾。
sort()
方法保留空槽。如果源数组是稀疏的,则空槽会被移动到数组的末尾,并始终排在所有 undefined
元素的后面。
备注: 在 UTF-16 中,Unicode 字符超出 \uFFFF
的范围会被编码为两个代理码元(surrogate code unit),这些码位的范围是 \uD800
到 \uDFFF
。每个码位的值都会被单独考虑进行比较。因此,由代理对 \uD855\uDE51
组成的字符将排在字符 \uFF3A
的前面。
如果提供了 compareFn
,所有非 undefined
的数组元素都会按照比较函数的返回值进行排序(所有的 undefined
元素都会被排序到数组的末尾,并且不调用 compareFn
)。
compareFn(a, b) 返回值 |
排序顺序 |
---|---|
> 0 | a 在 b 后,如 [b, a] |
< 0 | a 在 b 前,如 [a, b] |
=== 0 | 保持 a 和 b 原来的顺序 |
所以,比较函数形式如下:
JSCopy to Clipboard
function compareFn(a, b) {
if (根据排序标准,a 小于 b) {
return -1;
}
if (根据排序标准,a 大于 b) {
return 1;
}
// a 一定等于 b
return 0;
}
更正式地说,为了确保正确的排序行为,比较函数应具有以下属性:
- 纯函数:比较函数不会改变被比较的对象或任何外部状态。(这很重要,因为无法保证比较函数将在何时以及如何调用,因此任何特定的调用都不应对外部产生可见的效果。)
- 稳定性:比较函数对于相同的输入对应始终返回相同的结果。
- 自反性:
compareFn(a, a) === 0
。 - 反对称性:
compareFn(a, b)
和compareFn(b, a)
必须都是0
或者具有相反的符号。 - 传递性:如果
compareFn(a, b)
和compareFn(b, c)
都是正数、零或负数,则compareFn(a, c)
的符号与前面两个相同。