对于JavaScript中的特殊字符,localCompare和比较运算符之间的结果不同

时间:2017-04-03 11:26:33

标签: javascript sorting comparison

在查看与排序相关的一个问题时,我发现字符串localeCompare方法与条件运算符(如>,<)之间的非字母数字字符比较有趣的区别。

您可以通过在不同浏览器中运行以下代码段来查看它们之间的区别。

&#13;
&#13;
function comparison1(param1, param2){
  return param1 > param2;
}

function comparison2(param1, param2){
  return param1.localeCompare(param2);
}
document.getElementById("comparison11").innerHTML = comparison1('A', 'B');
document.getElementById("comparison12").innerHTML = comparison2('A', 'B');
document.getElementById("comparison21").innerHTML = comparison1('@', '_');
document.getElementById("comparison22").innerHTML = comparison2('@', '_');
&#13;
<div>
  <div style="float: left, width: 100%">
    'A' > 'B'
  </div>
  <div style="float: left, width: 100%" id="comparison11"></div>
  <div style="float: left, width: 100%">
    'A'.localeCompare('B')
  </div>
  <div style="float: left, width: 100%" id="comparison12"></div>
  <div style="float: left, width: 100%">
    '@' > '_'
  </div>
  <div style="float: left, width: 100%" id="comparison21"></div>
  <div style="float: left, width: 100%">
    '@'.localeCompare('_')<br/>
    <i>returns -1 in IE and Edge but 1 in Chrome and Firefox</i>
  </div>
  <div style="float: left, width: 100%" id="comparison22"></div>

</div>
<script>
</script>
&#13;
&#13;
&#13;

正如您所看到的,在比较&#39; @&#39;和&#39; _&#39;在Chrome和Firefox中使用localeCompare方法和>运算符时。

我们实现了针对具有不同数据类型的多个列调用的排序的比较方法。所以我们使用条件运算符,但正如您所看到的,它为不同浏览器中的非字母数字字符提供了不同的结果。

以下是我的问题!

为什么不同浏览器中特殊字符的不同响应?

什么是实现此目的的正确方法? (检查数据类型;如果字符串使用localeCompare else条件运算符?)

1 个答案:

答案 0 :(得分:3)

  

为什么不同浏览器中特殊字符的响应不同?

可能是因为正如ECMA-402 (internationalization) spec中所述:

  

Unicode的子集:某些操作(如排序规则)对可包含整个Unicode字符集中的字符的字符串进行操作。但是,Unicode标准和ECMAScript标准都允许实现将其功能限制为Unicode字符集的子集。此外,区域设置约定通常不会为整个Unicode字符集指定所需的行为,但仅针对与区域设置相关的那些字符。虽然Unicode归类算法将整个Unicode字符集的默认归类顺序与定制本地约定的能力相结合,但子集和定制仍然会导致行为上的差异。

最有可能的是,@_的顺序在您正在使用的区域(或我的;英国英语)中没有明确定义,因此您得到“行为上的差异。“

  

实现此目的的正确方法是什么? (检查数据类型;如果字符串使用localeCompare else条件运算符?)

是。 ><使用Unicode标准中代码点的数字关系,这根本不是处理排序规则的好方法,而localeCompare提供特定于语言环境的排序整理到角色。

要明确:当你说“...使用条件运算符”时,我假设你的意思是条件运算符(? :)与关系运算符({{1在这种情况下,或者>,例如类似的东西:

<

...或return a === b ? 0 : a > b ? 1 : -1; 回调中的类似内容。

但请注意,既然您现在正在使用sort字符串,而且唯一可以与localeCompare>进行真正有意义的比较是数字,那么有一个更好的解决方案数字如果你知道它们都不是<:只需减去:

NaN

(如果它们中的任何一个可能是return a - b; // For numbers that aren't NaN ,你就会想要处理它 - 也许是使用条件运算符。:-))