JavaScript sort() 排序的坑详解

发布于 2019-01-31  约 3 分钟

前言:做项目的时候发现使用sort排序后的代码,在android和ios平台解析的结果不一样。
clipboard.png

1、先从简单的开始,大家都知道sort()函数比较的是ASCII码的大小,而且而且而且:Array的sort()方法默认把所有元素先转换为String再排序,所以就有以下问题。

// baiDu排在了最后:
['Google', 'baiDu', 'Facebook'].sort(); // ['Facebook', 'Google", 'baiDu']

// 无法理解的结果:
[10, 20, 1, 2].sort(); // [1, 10, 2, 20]

结果转换成字符串比较,'10'排在了'2'的前面,因为字符'1'比字符'2'的ASCII码小

2、使用回调函数的错误

[10, 2, 3, 100, 6, 9].sort((a, b) => {
    return a < b;
});
// 无法理解的结果
[10, 2, 3, 100, 6, 9]

排序前后结果没有变化

问题分析:
在sort实现的规范中有这么一条 sortFun(a,b) === 0,则有 a === b 且 b === a 。
此时我们再看var sortFun = (a, b) => a < b,它等同于var sortFun = (a, b) => a < b ? 1 : 0。

它有一个隐藏的漏洞:当a >= b时,sortFun(a,b) === 0。而根据规范,通过sortFun(a,b) === 0可以推测出a === b,显然这里互相矛盾, 反之亦然(a > b的情况)。

所以比较的时候最好使用 a - b 或者 b - a

正确写法:

[10, 2, 3, 100, 6, 9].sort((a, b) => {
    return a - b;
});
// 结果
[2, 3, 6, 9, 10, 100]

android 和 ios平台解析的sort函数实现方式不同,不规范的写法可能导致解析结果不同

阅读 2.6k发布于 2019-01-31

推荐阅读

爱运动的程序员

52 人关注
129 篇文章
专栏主页
目录