- Published on
在JavaScript中将字符串首字母大写的方法
- Authors
- Name
在这个技术博客中,我们将探讨如何在JavaScript中将字符串的首字母大写。这样一个看似简单的问题,由于字符编码和国际化支持的复杂性,实际上具有许多隐藏的细节。我们将深入这些细节,并提供一些实用的代码示例来解决这些问题。
问题概述和解决方案
大多数提出的函数类似于以下代码:
function capitalizeFirstLetter(str) {
return str[0].toUpperCase() + str.slice(1)
}
但是,有些字符超出了BMP(基本多文种平面,代码点U+0到U+FFFF)。例如,处理Deseret文本时:
capitalizeFirstLetter('𐐶𐐲𐑌𐐼𐐲𐑉') // "𐐶𐐲𐑌𐐼𐐲𐑉"
这里的第一个字符无法大写,因为字符串的数组索引属性无法访问“字符”或代码点,它们访问的是UTF-16代码单元。
从ES2015起,处理这种情况变得稍微简单了一点。String.prototype[@@iterator]
可以按照代码点迭代字符串。因此,我们可以使用以下代码:
function capitalizeFirstLetter([first = '', ...rest]) {
return [first.toUpperCase(), ...rest].join('')
}
capitalizeFirstLetter('𐐶𐐲𐑌𐐼𐐲𐑉') // "𐐎𐐲𐑌𐐼𐐲𐑉"
对于较长的字符串,此方法可能效率不高,因为我们不需要遍历剩余部分。我们可以使用String.prototype.codePointAt
来获取第一个(可能的)字母,但仍需要确定切片的起始位置。
处理非BMP字符
function capitalizeFirstLetter(str) {
if (!str) return ''
const firstCP = str.codePointAt(0)
const index = firstCP > 0xffff ? 2 : 1
return String.fromCodePoint(firstCP).toUpperCase() + str.slice(index)
}
capitalizeFirstLetter('𐐶𐐲𐑌𐐼𐐲𐑉') // "𐐎𐐲𐑌𐐼𐐲𐑉"
国际化考虑
处理国际化时,有些语言需要特定的处理。例如,土耳其语中的“I”大写为“İ”,而小写形式的“I”是“ı”。
function capitalizeFirstLetter([first = '', ...rest], locale) {
return [first.toLocaleUpperCase(locale), ...rest].join('')
}
capitalizeFirstLetter('italy', 'en') // "Italy"
capitalizeFirstLetter('italya', 'tr') // "İtalya"
在浏览器中,可以使用navigator.language
来获取用户首选的语言标签,在多语言文档中,可以使用Object(element.closest('[lang]')).lang
来获取特定DOM元素的语言。
在支持Unicode字符属性类的环境中,可以进一步优化:
function capitalizeFirstLetter(str, locale = navigator.language) {
return str.replace(/^\p{CWU}/u, (char) => char.toLocaleUpperCase(locale))
}
通过CSS和HTML中的lang
属性及text-transform
属性,即使没有JavaScript,也可以处理文字的显示:
<!doctype html>
<dl>
<dt>未转换</dt>
<dd>ijsselmeer</dd>
<dt>使用CSS和<code>lang=en</code>大写</dt>
<dd lang="en" style="text-transform: capitalize">ijsselmeer</dd>
<dt>使用CSS和<code>lang=nl</code>大写</dt>
<dd lang="nl" style="text-transform: capitalize">ijsselmeer</dd>
</dl>
在Chromium中,英文和荷兰文的输出都为Ijsselmeer
。但是,在当前的Firefox中,我们可以看到荷兰文会正确显示为IJsselmeer
。
总的来说,即使这些国际化问题目前没有影响到你,但了解它们是很有必要的,因为你最终可能会遇到。