为什么Array.sort行为在Chrome和Node.js中不同

时间:2019-05-05 18:46:33

标签: javascript node.js v8

问题

让我们创建一个基本列表并对其进行排序,以确保2始终在列表中排在第一位。很简单,对吧?

[1, 2, 3].sort((a, b) => {
  if (a === 2) return -1;
  return 0;    
});

Chrome结果:✓

  

[2,1,3]

节点结果:X

  

[1、2、3]

为了在Node中获得此行为,您可以-奇怪的是-查看b参数,如果它是2,则使其返回1:

[1, 2, 3].sort((a, b) => {
  if (b === 2) return 1;
  return 0;    
});

通过此实现,您得到相反的结果; Chrome将为[1、2、3],Node为[2、1、3]。

问题

您对此行为有逻辑上的解释吗? 我的排序功能在概念上有缺陷吗?如果是这样,您将如何编写这种排序行为?

1 个答案:

答案 0 :(得分:4)

  

您对此行为有逻辑上的解释吗?

浏览器使用不同的排序方法。因此,他们可能以不同的顺序使用不同的参数调用提供的回调。如果您的排序功能不一致,则排序将不稳定。这将导致错误的排序顺序(在不同的输入数组中也总是如此,因此您的排序将永远无法正常进行)。

  

如果是这样,您将如何编写这种排序行为?

确保将这两个条件应用于所有可能的输入:

1)不应对两个相等的元素进行排序:

  sort(a, a) === 0

2)如果以相反的顺序调用sort函数,则结果也将相反:

  sort(a, b) - sort(b, a) === 0

在您的情况下,两个都没有满足:

  sort(2, 2) // 1 -> wrong!
  sort(2, 3) - sort(3, 2) // 1 -> wrong!

要编写稳定的排序,您必须查看a b

  function(a, b) {
    if(a === 2 && b === 2)
      return 0;
    if(a === 2)
      return 1;
    if(b === 2)
      return -1;
    return 0;
  }

或者更短一些:

  (a, b) => (a === 2) - (b === 2)