JavaScript sort() 排序的坑详解

7次阅读

共计 726 个字符,预计需要花费 2 分钟才能阅读完成。

前言:做项目的时候发现使用 sort 排序后的代码,在 android 和 ios 平台解析的结果不一样。
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 函数实现方式不同,不规范的写法可能导致解析结果不同

正文完
 0