在研究与排序相关的一个问题时,我发现了字符串之间的非字母数字字符比较的有趣差异localeCompare
方法和条件运算符(例如>,<
).
您可以通过在不同浏览器中运行以下代码片段来看到它们之间的差异。
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('@', '_');
<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>
正如您所看到的,在使用时比较“@”和“_”时,响应存在差异localeCompare
方法和>
Chrome 和 Firefox 中的运算符。
我们实现了用于排序的比较方法,该方法针对具有不同数据类型的多个列调用。因此我们使用了条件运算符,但正如您所看到的,它在不同的浏览器中为非字母数字字符提供不同的结果。
这是我的问题!
Why不同浏览器对特殊字符的响应不同?
What是正确的方法来实现这个吗? (检查数据类型;如果字符串使用 localeCompare else 条件运算符?)
为什么不同浏览器对特殊字符的响应不同?
可能是因为正如它所说ECMA-402(国际化)规范:
Unicode 的子集:某些操作(例如排序规则)对可以包含整个 Unicode 字符集中的字符的字符串进行操作。但是,Unicode 标准和 ECMAScript 标准都允许实现将其功能限制为 Unicode 字符集的子集。此外,区域设置约定通常不会指定整个 Unicode 字符集所需的行为,而仅指定与区域设置相关的那些字符。虽然 Unicode 排序算法将整个 Unicode 字符集的默认排序规则与针对本地约定进行定制的能力相结合,但子集和定制仍然会导致行为差异。
最有可能的顺序是@
vs. _
只是在您使用的区域设置(或我的;英国英语)中没有明确定义,所以您得到“行为上的差异。”
实施这个的正确方法是什么? (检查数据类型;如果字符串使用 localeCompare else 条件运算符?)
Yes. >
and <
使用 Unicode 标准中代码点的数字关系,这根本不是处理排序规则的好方法,而localeCompare
为字符提供特定于区域设置的排序规则。
需要明确的是:当你说你“...使用条件运算符”,我假设你的意思是条件运算符(? :
) 与关系运算符 (>
or <
在这种情况下),例如就像是:
return a === b ? 0 : a > b ? 1 : -1;
...或类似的sort
打回来。
但请注意,由于您现在正在使用localeCompare
对于字符串,唯一可以真正有意义地比较的东西>
and <
是数字,对于数字有更好的解决方案if你知道他们都不是NaN
:只需减去:
return a - b; // For numbers that aren't NaN
(如果其中任何一个可能是NaN
,您可能需要使用条件运算符来处理它。 :-) )
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)