Chrome环境和节点环境之间的“排序”方法有什么区别

时间:2019-05-27 05:50:03

标签: javascript node.js v8

我发现排序方法显示了在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

1 个答案:

答案 0 :(得分:4)

V8开发人员在这里。

随着一些评论的到来,这与Chrome vs. Node(其行为方式相同)无关。这是由于V8版本的差异,Chrome 74已经具有新的行为,而Node 10仍然具有旧的行为。更新到Node 11,您将在其中看到相同的行为。

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

(从7.4版开始的V8版本现在将TimSort用于Array.prototype.sort。)


我知道这不是这个问题,而是为了记录和/或将来其他任何人阅读: (pre, next) => pre <= next不是一个好的比较器功能!Array.prototype.sort期望比较器返回一个小于零,等于零或大于零的数字,具体取决于第一个参数是否小于,等于或大于第二个参数。因此,对字符串进行排序的正确方法是:

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

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

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