ES3

  1. var arr = [5, 3, 1, 2, 6, 4];
  2. var newArr = arr.sort();
  3. // 返回原数组的引用,不进行数组引用赋值
  4. newArr === arr // true

使用原地算法
在不同浏览器的引擎实现方案不一样

  • V8
    • arr.length <= 10 插入排序
    • arr.length >10 快速排序
  • Mozilla
    • 归并排序
  • Webkit
    • 使用C++ QSort 快速排序的理念

  1. // sort 并不会按照数字大小进行排序
  2. var arr = [5, 3, 1000, 1, 6];
  3. arr.sort(); // [1, 1000, 3, 5, 6]
  4. var arr = ['b', 'x', 'i', 'm', 'a', 'd'];
  5. arr.sort(); // ["a", "b", "d", "i", "m", "x"];
  6. var arr = [true, false];
  7. arr.sort(); // [false, true];

是以 toString -> 数组元素 -> 字符串
这个字符串是 DOMString -> UTF-16字符串实现 -> 映射到String -> 构建字符串
string -> UTF-16字符串 -> String/DOMString 的实例
即是按照 UTF-16 的编码顺序来进行排序

为什么要转成字符串

如果是仅限一种类型排序的话,sort 功能性就太弱
用字符串和字符编码集结合在一起形成排序规则,这样可以排序的范围就大了

  1. // 字符串的逐个字符进行编码位的排序
  2. var arr = ['abc', 'aba'];
  3. arr.sort(); // ["aba", "abc"]

参数 compareFunction

compareFunction就是自己写排序规则

比较函数方法,有两个参数

  • FElement
  • SElement

返回

  • 负数 a 就排在 b 前面
  • 正数 b 就排在 a 前面
  • 0 a 与 b 不进行排序

纯数字比较

  1. var arr = [5, 1, 2, 4, 6, 3, 3];
  2. arr.sort() // [1, 2, 3, 3, 4, 5, 6]
  3. arr.sort(function (a, b){
  4. // 没有写排序规则, 不进行任何排序操作
  5. })
  6. arr.sort(function (a, b){
  7. if(a < b) {
  8. return -1;
  9. }
  10. if(a > b) {
  11. return 1;
  12. }
  13. if(a === b) {
  14. return 0;
  15. }
  16. // 升序(小到大)
  17. return a - b;
  18. // 降序(大到小)
  19. return b - a;
  20. // 反转
  21. return -1;
  22. // 有作排序,但结果不变
  23. return 1;
  24. // 不变
  25. return 0;
  26. // 乱序
  27. return Math.random() - 0.5;
  28. })

compareFunction 必须对相同的输入有相同返回结果,结果不肯定(近似纯函数)

非 ASCII 字符串排序

对于字符串的比较要用 String.prototype.localeCompare() 方法来进行比较

  1. var arr = ['我', '爱', '你'];
  2. arr.sort((a, b) => {
  3. return a.localeCompare(b);
  4. });

大小写不一致的情况下都转为大写或小写

  1. var arr = [
  2. 'zhangsan',
  3. 'Xiaoye',
  4. 'MIKE',
  5. 'tony'
  6. ]
  7. // 这样子的话,每次比较形参都要进行一次转换,对性能负载较大
  8. arr.sort(() => {
  9. var _a = a.toLowerCase(),
  10. _b = b.toLowerCase();
  11. if(_a < _b) {
  12. return -1;
  13. }
  14. if(_a > _b) {
  15. return 1;
  16. }
  17. return 0
  18. });
  19. // 这时应该使用 map 先进行一次性在大写或小写化的对象映射,再进行比较
  20. var newArr = arr.map(function(item, index){
  21. var it = {
  22. index,
  23. value: item.toLowerCase()
  24. }
  25. return it;
  26. })
  27. newArr.sort((a, b) => {
  28. if(a.value > b.value) {
  29. return 1;
  30. }
  31. if(a.value < b.value) {
  32. return -1;
  33. }
  34. return 0;
  35. });
  36. var res = newArr.map(function (item){
  37. return arr[item.index];
  38. })