'sort' 方法在 chrome 环境和节点环境之间的区别是什么

what's the 'sort' method's difference between chrome environment and node environment

我发现排序方法在 Chrome 环境和节点环境

中表现出不同的行为
const arr = ['l', 'h', 'z', 'b', 's'];
arr.sort((pre, next) => {
    return pre < next;
});
console.log(arr);

节点环境的结果是[ 'z', 's', 'l', 'h', 'b' ],已排序。
chrome 控制台环境的结果是 ['l', 'h', 'z', 'b', 's'],没有任何改变。
chrome的结果是我所期望的,我不明白为什么它在节点环境中工作。

chrome 版本为 74.0.3729.169 X64
节点 vsrions 是 v10.12.0.

这里是 V8 开发人员。

正如一些评论所说,这不是关于 Chrome 与 Node(它们的行为方式应该相同)。这是由于 V8 版本的差异,其中 Chrome 74 已经具有新行为,而 Node 10 仍然具有旧行为。更新到节点 11,您会在那里看到相同的行为。

过去,V8 结合使用了 QuickSort(适用于较大的数组)和 InsertionSort(适用于小型数组,最多 10 个元素)。 InsertionSort 恰好与错误的比较器函数一起正常工作。使用包含 11 个或更多元素的测试数组,它在节点 10 中将不再正确排序。

(自 7.4 起的 V8 版本现在对 Array.prototype.sort 使用 TimSort。)


我知道这不是这个问题的问题,但为了记录 and/or 以后阅读此内容的任何其他人:(pre, next) => pre <= next 不是一个好的比较器函数! 在 JavaScript 中,Array.prototype.sort 需要一个比较器 returns 一个小于零、等于零或大于零的数字,具体取决于第一个参数是否小于,等于或大于第二个。所以对字符串进行排序的正确方法是这样的:

my_string_array.sort((a, b) => {
  if (a < b) return -1;
  if (a > b) return 1;
  return 0;
});

当你使用这样的比较器时,你总是会得到正确的结果,在所有版本的 Chrome 和 Node.

当您使用一个使用单一比较的比较器并因此 returns 一个布尔值时,然后 true 静默映射到 1 而 false 映射到 0,但这意味着它不小心 returns "equal" 对于一堆实际上不相等的对,这可能会导致非常令人惊讶的排序结果,尤其是当引擎在引擎盖下使用不稳定的排序算法时。