如何在 JavaScript 中使字符串的第一个字母大写?

问题描述:

如何使字符串的第一个字母大写,但不更改任何其他字母的大小写?

例如:

“这是一个测试”→“这是一个测试”

“埃菲尔铁塔”→“埃菲尔铁塔”

“/index.html”→“/index.html”

解决方案1:

huntsbot.com提供全网独家一站式外包任务、远程工作、创意产品分享与订阅服务!

基本解决方案是:

function capitalizeFirstLetter(string) { return string.charAt(0).toUpperCase() + string.slice(1); } console.log(capitalizeFirstLetter(‘foo’)); // 富

其他一些答案修改了 String.prototype(这个答案也曾经),但由于可维护性,我现在建议不要这样做(很难找出函数被添加到 prototype 的位置,并且如果其他代码使用可能会导致冲突同名/浏览器将来会添加同名的本机函数)。

…然后,当您考虑国际化时,这个问题还有很多,如 this astonishingly good answer(埋在下面)所示。

如果您想使用 Unicode 代码点而不是代码单元(例如处理基本多语言平面之外的 Unicode 字符),您可以利用 String#[@iterator] 与代码点一起使用的事实,并且您可以使用 toLocaleUpperCase 来获得语言环境正确的大写:

const capitalizeFirstLetter = ([ first, …rest ], locale = navigator.language) => first === undefined ? ‘’ : first.toLocaleUpperCase(locale) + rest.join(‘’) console.log( capitalizeFirstLetter(‘’), // [空字符串] capitalizeFirstLetter(‘foo’), // Foo capitalizeFirstLetter(“𐐶𐐲𐑌𐑉”), // “𐐎𐐲𐑌𐑉”(正确!) capitalizeFirstLetter(“italya”, ‘tr’) // İtalya"(土耳其拉丁语正确!)

如需更多国际化选项,请参阅original answer below。

此解决方案是正确的,但根据定义 The capitalize() method returns a string where the first character is upper case, and the rest is lower case.,如果任何其他字母是理想的大写字母 .toLowerCase() 也应添加到此答案的切片部分,这将失败。 function capitalizeFirstLetter(string) { return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); } console.log(capitalizeFirstLetter('foo'));

解决方案2:

huntsbot.com – 高效赚钱,自由工作

这是一种更面向对象的方法:

Object.defineProperty(String.prototype, 'capitalize', {
  value: function() {
    return this.charAt(0).toUpperCase() + this.slice(1);
  },
  enumerable: false
});

您将调用该函数,如下所示:

"hello, world!".capitalize();

预期输出为:

"Hello, world!"

@aggregate1166877 你能解释一下为什么吗?这个答案有近 1500 人支持。因此,如果没有任何解释,人们就会忽略你。像我一样,因为我会这样做。

@NielsLucas 够公平的。它有可能打破未来对 JS 的补充。如果它是只有您会使用的代码,那么它还不错 - 您只需更新您的代码并继续前进。这里真正的问题是当您开始使用这样的代码发布库时:您的代码使用您的代码修改每个库的内置行为。结果是,如果您和另一个库作者都用您自己的实现覆盖相同的内置函数,您会在另一个库的代码(或最后加载的代码)中创建错误,从而给用户留下无法重现的错误报告的调试地狱。

@aggregate1166877 感谢您的解释。我完全同意你的观点,这种方式不是创建库的好习惯,我也同意这种方式对项目来说很好。希望人们会读到这篇文章,因为我认为这是对原始答案的一个很好的关注。

抱歉,不,只是不要向基本类型添加任何功能。扩展它们? const ExtendedString = class extends String { capitalize () { return this[0].toUpperCase() + this.slice(1) } } const s = new ExtendedString('hello') console.log(s.capitalize())

很高兴看到作者在帖子中包含一些免责声明和有关扩展内置类型的详细信息。人们很难注意到评论。

解决方案3:

保持自己快人一步,享受全网独家提供的一站式外包任务、远程工作、创意产品订阅服务–huntsbot.com

在 CSS 中:

p::first-letter {
    text-transform:capitalize;
}

$('#mystring_id').text(string).css('text-transform','capitalize');

此外,这只影响字符串的显示 - 而不是实际值。例如,如果它在一个表单中,该值仍将按原样提交。

这不是 JS,但我敢打赌,对于 99% 的读者来说,这是最好的答案。我当然很高兴我滚动了这么远🙃

此外,::first-letter 仅适用于 display 值为 block、inline-block、table-cell、list-item 或 table-caption 的元素。在所有其他情况下,::first-letter 无效。

解决方案4:

huntsbot.com提供全网独家一站式外包任务、远程工作、创意产品分享与订阅服务!

这是流行答案的缩短版本,它通过将字符串视为数组来获取第一个字母:

function capitalize(s)
{
    return s[0].toUpperCase() + s.slice(1);
}

更新

根据下面的评论,这在 IE 7 或更低版本中不起作用。

更新 2:

为避免 undefined 出现空字符串(请参阅 @njzk2’s comment below),您可以检查空字符串:

function capitalize(s)
{
    return s && s[0].toUpperCase() + s.slice(1);
}

ES版

const capitalize = s => s && s[0].toUpperCase() + s.slice(1)

// to always return type string event when s may be falsy other than empty-string
const capitalize = s => (s && s[0].toUpperCase() + s.slice(1)) || ""

只需使用 charAt() 而不是 []

解决方案5:

huntsbot.com洞察每一个产品背后的需求与收益,从而捕获灵感

如果您对发布的几种不同方法的性能感兴趣:

以下是基于 this jsperf test 的最快方法(从最快到最慢排序)。

如您所见,前两种方法在性能方面基本相当,而更改 String.prototype 在性能方面是迄今为止最慢的。

// 10,889,187 operations/sec
function capitalizeFirstLetter(string) {
    return string[0].toUpperCase() + string.slice(1);
}

// 10,875,535 operations/sec
function capitalizeFirstLetter(string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
}

// 4,632,536 operations/sec
function capitalizeFirstLetter(string) {
    return string.replace(/^./, string[0].toUpperCase());
}

// 1,977,828 operations/sec
String.prototype.capitalizeFirstLetter = function() {
    return this.charAt(0).toUpperCase() + this.slice(1);
}

https://i.stack.imgur.com/tNwKk.png

我想知道为什么最后一种方法这么慢,你每次迭代都将函数附加到原型上吗?那是不公平的

解决方案6:

huntsbot.com全球7大洲远程工作机会,探索不一样的工作方式

在与星体平面代码点或国际化相关的问题的现有答案中,我没有看到任何提及。 “大写”在使用给定脚本的每种语言中并不意味着相同的东西。

最初我没有看到任何解决与星体平面代码点相关的问题的答案。有 is one,但它有点被埋没了(我猜这一个会是这样!)

大多数建议的功能如下所示:

function capitalizeFirstLetter(str) {
  return str[0].toUpperCase() + str.slice(1);
}

但是,一些大小写字符不在 BMP(基本多语言平面,代码点 U+0 到 U+FFFF)之外。例如,以这个 Deseret 文本为例:

capitalizeFirstLetter("𐐶𐐲𐑌𐐼𐐲𐑉"); // "𐐶𐐲𐑌𐐼𐐲𐑉"

这里的第一个字符没有大写,因为字符串的数组索引属性不访问“字符”或代码点*。他们访问 UTF-16 代码单元。切片时也是如此——索引值指向代码单元。

碰巧 UTF-16 代码单元是 1:1,USV 代码点在两个范围内,U+0 到 U+D7FF 和 U+E000 到 U+FFFF 包括在内。大多数大小写字符都属于这两个范围,但不是全部。

从 ES2015 开始,处理这个变得更容易了。 String.prototype[@@iterator] 产生对应于代码点的字符串**。例如,我们可以这样做:

function capitalizeFirstLetter([ first, ...rest ]) {
  return [ first.toUpperCase(), ...rest ].join('');
}

capitalizeFirstLetter("𐐶𐐲𐑌𐐼𐐲𐑉") // "𐐎𐐲𐑌𐐼𐐲𐑉"

对于较长的字符串,这可能不是非常有效***——我们真的不需要迭代其余部分。我们可以使用 String.prototype.codePointAt 来获取第一个(可能的)字母,但我们仍然需要确定切片应该从哪里开始。避免迭代剩余部分的一种方法是测试第一个代码点是否在 BMP 之外;如果不是,则切片从 1 开始,如果是,则切片从 2 开始。

function capitalizeFirstLetter(str) {
  const firstCP = str.codePointAt(0);
  const index = firstCP > 0xFFFF ? 2 : 1;

  return String.fromCodePoint(firstCP).toUpperCase() + str.slice(index);
}

capitalizeFirstLetter("𐐶𐐲𐑌𐐼𐐲𐑉") // "𐐎𐐲𐑌𐐼𐐲𐑉"

您可以在此处使用按位数学而不是 > 0xFFFF,但这种方式可能更容易理解,并且两者都可以达到相同的效果。

我们也可以在 ES5 及更低版本中实现这项工作,如果必要的话,可以通过更进一步的逻辑来实现。 ES5 中没有用于处理代码点的内在方法,因此我们必须手动测试第一个代码单元是否是代理****:

function capitalizeFirstLetter(str) {
  var firstCodeUnit = str[0];

  if (firstCodeUnit < '\uD800' || firstCodeUnit > '\uDFFF') {
    return str[0].toUpperCase() + str.slice(1);
  }

  return str.slice(0, 2).toUpperCase() + str.slice(2);
}

capitalizeFirstLetter("𐐶𐐲𐑌𐐼𐐲𐑉") // "𐐎𐐲𐑌𐐼𐐲𐑉"

一开始我也提到了国际化的考虑。其中一些很难解释,因为它们不仅需要了解正在使用的语言,而且可能需要了解该语言中的单词的具体知识。例如,爱尔兰二合字母“mb”在单词开头大写为“mB”。另一个例子,德语 eszett,从不开始一个词 (afaik),但仍然有助于说明问题。小写的 eszett (“ß”) 大写为“SS”,但“SS”可以小写为“ß”或“ss”——您需要德语的带外知识才能知道哪个是正确的!

这类问题最著名的例子可能是土耳其语。在土耳其拉丁语中,i 的大写形式是 İ,而 I 的小写形式是 ı——它们是两个不同的字母。幸运的是,我们确实有办法解决这个问题:

function capitalizeFirstLetter([ first, ...rest ], locale) {
  return [ first.toLocaleUpperCase(locale), ...rest ].join('');
}

capitalizeFirstLetter("italy", "en") // "Italy"
capitalizeFirstLetter("italya", "tr") // "İtalya"

在浏览器中,用户最喜欢的语言标签由 navigator.language 表示,在 navigator.languages 处可以找到按优先顺序排列的列表,并且(通常)可以在多语言文档中使用 Object(element.closest(‘[lang]’)).lang || YOUR_DEFAULT_HERE 获得给定 DOM 元素的语言.

在支持 ES2018 中引入的 RegExp 中的 Unicode 属性字符类的代理中,我们可以通过直接表达我们感兴趣的字符来进一步清理内容:

function capitalizeFirstLetter(str, locale=navigator.language) {
  return str.replace(/^\p{CWU}/u, char => char.toLocaleUpperCase(locale));
}

这可以稍微调整一下,以处理字符串中多个单词的大写,并具有相当好的准确性。 CWU 或 Changes_When_Uppercased 字符属性匹配所有代码点,这些代码点在大写时会发生变化。我们可以用像荷兰语 ij 这样的带标题的二合字母来试试这个,例如:

capitalizeFirstLetter('ijsselmeer'); // "IJsselmeer"

截至 2021 年 1 月,所有主要引擎都实现了 Unicode 属性字符类功能,但根据您的目标支持范围,您可能还无法安全使用它。最后一个引入支持的浏览器是 Firefox(78;2020 年 6 月 30 日)。您可以使用 Kangax compat table 检查是否支持此功能。 Babel 可用于编译带有属性引用的 RegExp 文字到没有它们的等效模式,但请注意,生成的代码有时可能会很大。除非您确定权衡对于您的用例是合理的,否则您可能不想这样做。

问这个问题的人很可能不会关心 Deseret 的大写或国际化。但是,了解这些问题是件好事,因为即使它们目前不是问题,您最终也很有可能会遇到它们。它们不是“边缘”案例,或者更确切地说,它们不是定义的边缘案例——无论如何,在整个国家,大多数人都说土耳其语,并且将代码单元与代码点混为一谈是相当常见的错误来源(尤其是与关于表情符号)。字符串和语言都非常复杂!

  • UTF-16 / UCS2 的代码单元在某种意义上也是 Unicode 代码点,例如 U+D800 在技术上是一个代码点,但这不是它在这里的“含义”…有点…虽然它变得很漂亮模糊。但是,代理绝对不是 USV(Unicode 标量值)。

** 虽然如果代理代码单元是“孤立的”——即,不是逻辑对的一部分——你仍然可以在这里获得代理。

*** 也许。我没有测试过。除非你已经确定大写是一个有意义的瓶颈,否则我可能不会担心——选择你认为最清晰易读的任何内容。

**** 这样的函数可能希望同时测试第一个和第二个代码单元,而不仅仅是第一个,因为第一个单元可能是孤立的代理。例如,输入“\uD800x”将按原样大写 X,这可能是预期的,也可能不是预期的。

我一直想知道为什么 toUpperCase 对某些语言并没有真正做太多......但并没有足够在意去找出答案。很高兴我终于做到了,这是一本非常有趣的书!

这似乎不适用于荷兰语中的“IJ”等二合字母。使用最新版本,此处的示例被错误地大写为“Ijsselmeer”(正则表达式版本)。我使用的代码是:capitalizeFirstLetter('ijssel', 'nl-NL') - 这是一个正确的本地化字符串,对吧?

“ij”为 U+69,U+6A 将大写为“Ij”,是的 - “ij”(U+133,单个代码点)大写为“IJ”(U+132)。此处的区域设置意识仅扩展到 Unicode 定义的大小写映射规则,这些规则有时因语言而异,如土耳其语;知道 "ij" (U+69, U+6A) 是否应该解释为 ij (U+133) 超出了它的范围,并且至少需要该语言的字典。

@paul23 您写的是 ij(2 个字母)而不是 ij(1 个字母)。

在荷兰,荷兰语 IJ 被认为是 2 个字母,它们只是同时大写(与比利时版本相反)。

解决方案7:

一个优秀的自由职业者,应该有对需求敏感和精准需求捕获的能力,而huntsbot.com提供了这个机会

对于另一种情况,我需要将第一个字母大写,其余字母小写。以下情况使我更改了此功能:

//es5
function capitalize(string) {
    return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
}
capitalize("alfredo")  // => "Alfredo"
capitalize("Alejandro")// => "Alejandro
capitalize("ALBERTO")  // => "Alberto"
capitalize("ArMaNdO")  // => "Armando"

// es6 using destructuring 
const capitalize = ([first,...rest]) => first.toUpperCase() + rest.join('').toLowerCase();

解决方案8:

huntsbot.com提供全网独家一站式外包任务、远程工作、创意产品分享与订阅服务!

这是 2018 ECMAScript 6+ 解决方案:

const str = ‘埃菲尔铁塔’; const newStr = ${str[0].toUpperCase()}${str.slice(1)}; console.log(‘原始字符串:’, str); // 埃菲尔铁塔 console.log(‘New String:’, newStr); // 艾菲尔铁塔

解决方案9:

huntsbot.com – 高效赚钱,自由工作

如果您已经(或正在考虑)使用 Lodash,解决方案很简单:

_.upperFirst('fred');
// => 'Fred'

_.upperFirst('FRED');
// => 'FRED'

_.capitalize('fred') //=> 'Fred'

查看他们的文档:https://lodash.com/docs#capitalize

_.camelCase(‘Foo Bar’); //=> ‘fooBar’

https://lodash.com/docs/4.15.0#camelCase

_.lowerFirst('Fred');
// => 'fred'

_.lowerFirst('FRED');
// => 'fRED'

_.snakeCase('Foo Bar');
// => 'foo_bar'

第一个大写的 Vanilla JavaScript:

function upperCaseFirst(str){
    return str.charAt(0).toUpperCase() + str.substring(1);
}

我认为应该首选 vanilla Js,因为大多数人不会下载整个框架只是为了大写一个字符串。

到目前为止,在我的所有项目中,我从未使用过 lodash。不要忘记,谷歌上的大多数人都会在这个页面上结束,列出一个框架作为替代方案很好,但不是主要答案。

@GGG 到目前为止,我在所有项目中都使用过 lodash

Vanilla js 比 lodash 更好。没有人再使用它了。

@chovy 我在 npm 上查找了它,它在过去一周内有约 40,276,984 次下载,并且依赖于约 144k 包。我不会说没有人使用它。

解决方案10:

保持自己快人一步,享受全网独家提供的一站式外包任务、远程工作、创意产品订阅服务–huntsbot.com

将字符串中所有单词的首字母大写:

function ucFirstAllWords( str )
{
    var pieces = str.split(" ");
    for ( var i = 0; i < pieces.length; i++ )
    {
        var j = pieces[i].charAt(0).toUpperCase();
        pieces[i] = j + pieces[i].substr(1);
    }
    return pieces.join(" ");
}

重读问题:我想将字符串的第一个字符大写,但不更改任何其他字母的大小写。

我知道我做到了。我会添加一件事,以防整个字符串开始大写:pieces[i] = j + pieces[i].substr(1).toLowerCase();

这种情况的另一种解决方案: function capitaliseFirstLetters(s) { return s.split(" ").map(function(w) { return w.charAt(0).toUpperCase() + w.substr(1) }).join (" ") } 如果它没有放入函数中,它可以是一个很好的单行。

最好先小写整个字符串

除了这个函数没有回答问题之外,它实际上也过于复杂了。 s => s.split(' ').map(x => x[0].toUpperCase() + x.slice(1)).join(' ')

解决方案11:

huntsbot.com聚合了超过10+全球外包任务平台的外包需求,寻找外包任务与机会变的简单与高效。

有一种非常简单的方法可以通过替换来实现。对于 ECMAScript 6:

'foo'.replace(/^./, str => str.toUpperCase())

结果:

'Foo'

迄今为止的最佳答案,以及显示正则表达式 lambda 语法的额外要点。我特别喜欢这个,因为它可以在任何地方进行流畅的剪切和粘贴。

使用 /^[a-z]/i 会比使用 . 更好,因为前一个不会尝试替换字母以外的任何字符

确实很聪明!

@CodeManiac 除了 [az] 之外,还有很多语言和字母

原文链接:https://www.huntsbot.com/qa/vePD/how-do-i-make-the-first-letter-of-a-string-uppercase-in-javascript?lang=zh_CN

HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值