明明‘a'大于'A',为什么localeCompare返回-1?

在字符编码里:
小写 > 大写 > 数字
那应该
'a'.localeCompare('A') // 我觉得应该返回1
可结果是返回-1
其它:
'A'.localeCompare('a') // 1
'Z'.localeCompare('z') // 1
'Z'.localeCompare('a') // 1

这是什么情况?跟我理解的不一样啊。
数组排序又没问题,但字符比较时却是大写 > 小写

阅读 2.2k
3 个回答
✓ 已被采纳新手上路,请多包涵

localeCompare方法是个比排序的方法,不是比大小的方法。

比大小”的规则逻辑:按字符编码的编号大小比。
比排序”的规则逻辑:数字 < 字母,小写字母 < 大写字母,大小写的A < 大小写的Z,其它字符的内定排序规则。


确实是由于 referenceStr.localeCompare(compareString[, locales[, options]]) 中的 locales 所影响的。规范没有说明这个函数应该如何表现,并且不同的项目组对于API的实现有自己的想法。

你可以复制以下示例在终端中输出不同的 locales 对于 localeCompare 的影响:

const testArray=["Ă","Â","Î","Ș","Ț","A","i","I","S","T","é","e","ä","a","𝒶","𝕒","Д","д", "å", "z"]
const locales=["POSIX", "en-US-u-va-posix", "und", "en", "da", "ru"]

console.log(`${testArray.sort().join("")} sort()`)

console.log(`${testArray.sort((a,b)=>a.localeCompare(b)).join("")} localeCompare(x)`)

locales.forEach(locale => {
  const f = (a,b) => a.localeCompare(b, locale)
  try{
    console.log(`${testArray.sort(f).join("")} ${locale}`)
  } catch(e) {
    console.log(`${locale}: ${e}`)
  }
})

在我的 Chrome 105.0.5195.52/Windows 中输出的结果为:

AISTaeizÂÎäåéĂȘȚДд𝒶𝕒 sort()
a𝒶𝕒AĂÂåäéeiIÎSȘTȚzдД localeCompare(x)
a𝒶𝕒AĂÂåäéeiIÎSȘTȚzдД POSIX
a𝒶𝕒AĂÂåäeéiIÎSȘTȚzдД en-US-u-va-posix
a𝒶𝕒AĂÂåäéeiIÎSȘTȚzдД und
a𝒶𝕒AĂÂåäeéiIÎSȘTȚzдД en
Aa𝒶𝕒ĂÂeéIiÎSȘTȚzäåДд da
дДa𝒶𝕒AĂÂåäeéiIÎSȘTȚz ru

而在 Node v16.16.0/Windows 环境中输出结果为:

AISTaeizÂÎäåéĂȘȚДд𝒶𝕒 sort()
a𝒶𝕒AĂÂåäéeiIÎSȘTȚzдД localeCompare(x)
a𝒶𝕒AĂÂåäéeiIÎSȘTȚzдД POSIX
𝒶𝕒AĂÂIÎSȘTȚaåäeéizдД en-US-u-va-posix
a𝒶𝕒AĂÂåäéeiIÎSȘTȚzдД und
a𝒶𝕒AĂÂåäeéiIÎSȘTȚzдД en
Aa𝒶𝕒ĂÂeéIiÎSȘTȚzäåДд da
дДa𝒶𝕒AĂÂåäeéiIÎSȘTȚz ru

可以对比着看到当 localesen-US-u-va-posix 时,排序的结果出现了差异。

a𝒶𝕒AĂÂåäeéiIÎSȘTȚzдД en-US-u-va-posix // chrome
𝒶𝕒AĂÂIÎSȘTȚaåäeéizдД en-US-u-va-posix // node

如果说想要简单的实现对于字母和数字的排序可以使用 sort 方法,这个还是很固定的。

const list = Array.from('a3b1EAK2Bdc')
console.log(list.sort().join(""))
// 123ABEKabcd

了解更多详细:

localeCompare 是根据 locale 的比较规则来比较,不是按字符编码的。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏