博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JavaScript中的Array.prototype.sort方法详解
阅读量:6432 次
发布时间:2019-06-23

本文共 2069 字,大约阅读时间需要 6 分钟。

前几天在某公司面试的时候被问到关于这个方法的默认值的问题(然而面试官跟我说的其实是错的,当场我还不够底气去反驳)。突然发现对这个方法的了解还不够,因此回来查了资料,看了v8引擎的实现和ECMA标准,在这分享一下我的总结。

先给几个结论把,然后我们再从ECMA标准去看这个方法。

  1. sort方法会修改原本数组。
  2. sort方法是不稳定的。
  3. sort方法可以接受一个可选的参数,comparefn(比较回调函数)。
  4. sort方法始终是默认升序的。

1.sort方法会修改原本数组

let a = [1, 20, 13, 110]a.sort()console.log(a) // 输出[1, 110, 13, 20]

如上,a在调用sort方法后,自身数组被修改。


2.sort方法是不稳定的

这句话具体来说应该是,sort方法在长数组排序的时候是不稳定的。在v8引擎的里,对于短数组会使用插入排序,而插入排序是稳定的。对于长数组会使用快速排序,而快速排序一般是不稳定的。具体可以读v8引擎的代码,,从710行开始。


3.sort方法可以接受一个可选的参数,ccomparefn(比较回调函数)。

我们来看一下v8引擎中关于这一部分的代码

if (!IS_CALLABLE(comparefn)) {    comparefn = function (x, y) {      if (x === y) return 0;      if (%_IsSmi(x) && %_IsSmi(y)) {        return %SmiLexicographicCompare(x, y);      }      x = TO_STRING(x);      y = TO_STRING(y);      if (x == y) return 0;      else return x < y ? -1 : 1;    };  }

可以看出,在不传递comparefn这个参数的情况下,默认会使用转换为的字符串的诸个字符的Unicode位点进行排序。另外值得注意的一点是,undefined在默认情况下总是会被排在数组的最后,这一点可以参考中关于Array.prototype.sort(comparefn)的描述。

When the SortCompare operatoris called with two arguments x and y, the

following steps are taken:

  1. If x and y are both undefined, return +0.
  2. If x is undefined, return 1.
  3. If y is undefined, return −1.
  4. If the argument comparefn was not provided in the call to sort, go to step 7.
  5. Call comparefn with arguments x and y.
  6. Return Result(5).
  7. Call ToString(x).
  8. Call ToString(y).
  9. If Result(7) < Result(8), return −1.
  10. If Result(7) > Result(8), return 1.
  11. Return +0.

以下是我简单翻译的规则:

当比较操作函数用x,y两个参数调用的时候,会按照接下来的步骤进行:

  1. 如果x,y都是undefined,返回 +0
  2. 如果x是undefined,返回 1
  3. 如果y是undefined,返回 -1
  4. 如果没有提供comparefn,跳至第七步
  5. 用comparefn比较x,y
  6. 返回第五步的比较结果
  7. x.toString()
  8. y.toString()
  9. 如果第八步大于第七步,返回-1
  10. 如果第七步大于第八步,返回1
  11. 返回+0

因此[1, 20, 2, 10].sort()的结果会是[1, 10, 2, 20],而不是预期的[1, 2, 10, 20]。


4. sort方法始终是默认升序的。

另外关于如何根据x,y比较结果进行排序,有以下规则:

  • 如果 comparefn(a, b) 小于 0 ,那么 a 会被排列到 b 之前;
  • 如果 comparefn(a, b) 等于 0 , a 和 b 的相对位置不变。备注: ECMAScript 标准并不保证这一行为,而且也不是所有浏览器都会遵守(例如 Mozilla 在 2003 年之前的版本, 例如v8引擎, 这一点其实就是上面所说的排序不稳定);
  • 如果 comparefn(a, b) 大于 0 , b 会被排列到 a 之前。

所以sort方法返回的数组永远是该方法认为的升序数组。我们要做的事情就是令我们想要放在后面的数大于放在前面的数。

比如我们想要返回一个降序的数字数组传入的comparefn应该是 (a, b) => b - a

参考资料:

转载地址:http://ygxga.baihongyu.com/

你可能感兴趣的文章
洛谷2219:[HAOI2007]修筑绿化带——题解
查看>>
监控webservice信息
查看>>
a标签中href=""的几种用法(转)
查看>>
python
查看>>
ubuntu 常用生产环境部署配置测试调优
查看>>
【JS】//将中文逗号转换为英文逗号
查看>>
在VS2012中实现Ext JS的智能提示太简单了
查看>>
Extnet Direct 提交后台事件文件下载设置
查看>>
邻接矩阵与二叉排序树
查看>>
CSS选择器
查看>>
购物车练习
查看>>
js实现在表格中删除和添加一行
查看>>
SOCKET简单爬虫实现代码和使用方法
查看>>
导出excel数字变成科学计数法解决办法
查看>>
跨域解决方案汇总
查看>>
In App Purchase
查看>>
C#向win32程序窗口中的文本框设置指定文本
查看>>
js判断对象的类型的四种方式
查看>>
ETL (数据仓库技术)
查看>>
ping广播地址会如何(转)
查看>>