ES3
var arr = [5, 3, 1, 2, 6, 4];var newArr = arr.sort();// 返回原数组的引用,不进行数组引用赋值newArr === arr // true
使用原地算法
在不同浏览器的引擎实现方案不一样
- V8
- arr.length <= 10 插入排序
- arr.length >10 快速排序
- Mozilla
- 归并排序
- Webkit
- 使用C++ QSort 快速排序的理念
// sort 并不会按照数字大小进行排序var arr = [5, 3, 1000, 1, 6];arr.sort(); // [1, 1000, 3, 5, 6]var arr = ['b', 'x', 'i', 'm', 'a', 'd'];arr.sort(); // ["a", "b", "d", "i", "m", "x"];var arr = [true, false];arr.sort(); // [false, true];
是以 toString -> 数组元素 -> 字符串
这个字符串是 DOMString -> UTF-16字符串实现 -> 映射到String -> 构建字符串
string -> UTF-16字符串 -> String/DOMString 的实例
即是按照 UTF-16 的编码顺序来进行排序
为什么要转成字符串
如果是仅限一种类型排序的话,sort 功能性就太弱
用字符串和字符编码集结合在一起形成排序规则,这样可以排序的范围就大了
// 字符串的逐个字符进行编码位的排序var arr = ['abc', 'aba'];arr.sort(); // ["aba", "abc"]
参数 compareFunction
compareFunction就是自己写排序规则
比较函数方法,有两个参数
- FElement
- SElement
返回
- 负数 a 就排在 b 前面
- 正数 b 就排在 a 前面
- 0 a 与 b 不进行排序
纯数字比较
var arr = [5, 1, 2, 4, 6, 3, 3];arr.sort() // [1, 2, 3, 3, 4, 5, 6]arr.sort(function (a, b){// 没有写排序规则, 不进行任何排序操作})arr.sort(function (a, b){if(a < b) {return -1;}if(a > b) {return 1;}if(a === b) {return 0;}// 升序(小到大)return a - b;// 降序(大到小)return b - a;// 反转return -1;// 有作排序,但结果不变return 1;// 不变return 0;// 乱序return Math.random() - 0.5;})
compareFunction 必须对相同的输入有相同返回结果,结果不肯定(近似纯函数)
非 ASCII 字符串排序
对于字符串的比较要用 String.prototype.localeCompare() 方法来进行比较
var arr = ['我', '爱', '你'];arr.sort((a, b) => {return a.localeCompare(b);});
大小写不一致的情况下都转为大写或小写
var arr = ['zhangsan','Xiaoye','MIKE','tony']// 这样子的话,每次比较形参都要进行一次转换,对性能负载较大arr.sort(() => {var _a = a.toLowerCase(),_b = b.toLowerCase();if(_a < _b) {return -1;}if(_a > _b) {return 1;}return 0});// 这时应该使用 map 先进行一次性在大写或小写化的对象映射,再进行比较var newArr = arr.map(function(item, index){var it = {index,value: item.toLowerCase()}return it;})newArr.sort((a, b) => {if(a.value > b.value) {return 1;}if(a.value < b.value) {return -1;}return 0;});var res = newArr.map(function (item){return arr[item.index];})
