DEV Community

Web Basics: How to Capitalize a Word in JavaScript

Samantha Ming on January 31, 2019

Back to another round of Web Basics. In the last one, we learned How to Reverse a String in Javascript. By the way, for those new to my community...
Collapse
 
itachiuchiha profile image
Itachi Uchiha

I have a function exactly do that. (I use this function for 3 years. I just changed for new ES standards)

const capitalize = (str) => {
  return str
    .toLowerCase()
    .split(' ')
    .map(strWord => strWord.substring(0, 1).toUpperCase() + strWord.substring(1, strWord.length))
    .join(' ')
}

In this example, this function firstly takes a string.

After that, the whole string will be lowercase.

After that, the string will be split with empty spaces. (Ex: I HAVE NO IDEA)

Now, we have words array. I use the map method to manipulate the array.

We'll take the first letter of the word. This letter will be uppercase. The others will be lowercase.

If you know how the substring method works, you won't be confused.

And the last one, we'll concatenate the words to create our new string. That's all.

Collapse
 
reegodev profile image
Matteo Rigon • Edited
const capitalize = (str) => {
    return str
        .split('')
        .map((c,i) => i ? c.toLowerCase() : c.toUpperCase())
        .join('')
}

Might be more performant since you have to loop the array anyway

Collapse
 
qm3ster profile image
Mihail Malo • Edited

You can just map on the string :v

const capitalize = str =>
  Array.prototype.map
    .call(str, (c, i) => i ? c.toLowerCase() : c.toUpperCase())
    .join('')

But no, it's most likely not going to be performant (even like this), because it involves indexing into every character instead of handing the underlying native string to the native method.

Worse yet, .split('') and such don't play well with composite Unicode graphemes.

Collapse
 
samanthaming profile image
Samantha Ming

Woo, I love this solution! Nice use to the falsy value to check the first character (cause 0 is false). Thanks for sharing 💯

Collapse
 
qm3ster profile image
Mihail Malo • Edited

You can omit the second argument in substring, substr and slice to get the rest of the string until the end.
You can also use charAt(0) or even .charAt() to get the first char instead of a slicing method.

const capitalize = str => str
  .toLowerCase()
  .split(' ')
  .map(strWord => strWord.charAt().toUpperCase() + strWord.slice(1))
  .join(' ')
Collapse
 
samanthaming profile image
Samantha Ming

Nice use to map! And awesome explanation with it! Thanks for sharing 🤓

Collapse
 
josemunoz profile image
José Muñoz

here's my take on it with ES7

const capitalize = ([initial, ...rest]) => `${initial.toUpperCase()}${rest.join('').toLowerCase()}`;

a little cleaner

const capitalize = input => {
  const [initial, ...rest] = input;
  const capitalizedInitial = initial.toUpperCase();
  const loweredBody = rest.join('').toLowerCase();

  return `${capitalizedInitial}${loweredBody}`;
};
Collapse
 
kurisutofu profile image
kurisutofu • Edited
const [initial, ...rest] = input;

I didn't think of it that way. I like it!

Collapse
 
samanthaming profile image
Samantha Ming

One-liner solutions are most of the time my favs too! 😜

Collapse
 
qm3ster profile image
Mihail Malo

TextDecoder solution:

{
  const encoder = new TextEncoder()
  const decoder = new TextDecoder()
  const capitalizeASCIIalphanum = str => {
    const arr = encoder.encode(str)
    const len = arr.length
    let val = arr[0]
    if (val > 0x60) arr[0] = val - 0x20
    for (let i = 1; i < len; i++) {
      val = arr[i]
      if (val < 0x5b) arr[i] = val + 0x20
    }
    return decoder.decode(arr)
  }


  const { log } = console
  log(capitalizeASCIIalphanum("hello"))
  log(capitalizeASCIIalphanum("GREAT"))
  log(capitalizeASCIIalphanum("aWESOME"))
}

Many checks are missing. This is intentional, because we are going to pretend that this is performant.

Collapse
 
qm3ster profile image
Mihail Malo • Edited

String.prototype.replace(regex, fn) solution:

{
  const reWord = /(\w)(\w*)/g
  const replacer = (_, head, tail) => head.toUpperCase() + tail.toLowerCase()
  const capitalize = str => str.replace(reWord, replacer)


  console.log(capitalize("hello GREAT\taWESOME\nyeoss"))
}
Collapse
 
diek profile image
diek

If you only want the first word capitalized:

'mi texto sin caPPPPitalizar'.toLowerCase().replace(/^[a-z]/i,(c)=>c.toUpperCase());
// output: "Mi texto sin cappppitalizar"
Collapse
 
diek profile image
diek
'mi texto sin caPPPPitalizar'.toLowerCase().replace(/\b\w/gi,(c)=> c.toUpperCase());
Collapse
 
qm3ster profile image
Mihail Malo • Edited

This is probably the best multi-word solution.
I totally forgot about \b, it is excellent.
I totally emulated it with /(?:^|\s)\w/, since capitalizing the whitespace doesn't do anything, but this is just so much better!

Does the i flag improve performance and not harm it though?

I'd potentially hoist the regex and callback constructions out of the function, although that may be crazy to do.

Thread Thread
 
diek profile image
diek

Hi, the i doesn't does anything in this case, it is my mania of writing it always. The mdn's docu says this about \w:

Matches any alphanumeric character from the basic Latin alphabet, including the underscore. Equivalent to [A-Za-z0-9_]

So \w is case insesitive already.

Thread Thread
 
qm3ster profile image
Mihail Malo • Edited

OH NO

'mi ke$ha'.toLowerCase().replace(/\b\w/gi, c => c.toUpperCase())
//> "Mi Ke$Ha"

:'(

Thread Thread
 
diek profile image
diek

That was expected, which result do you wanted?

Thread Thread
 
qm3ster profile image
Mihail Malo

Try my honestly unironically inferior regex and see:

'mi ke$ha'.toLowerCase().replace(/(?:^|\s)\w/g, c => c.toUpperCase())
Collapse
 
samanthaming profile image
Samantha Ming

regex ahhhh 😅 I need to get better at that cause I know how powerful it is 😆

Collapse
 
kurisutofu profile image
kurisutofu • Edited

Not as fancy as other solutions but I believe this works.

const capitalize = (str) => str.charAt(0).toUpperCase() + str.substr(1).toLowerCase();
Collapse
 
samanthaming profile image
Samantha Ming

No need to always be fancy. This works perfectly! Great 👍

Collapse
 
jmurray90 profile image
Jake Murray

Awesome guide!
This is one situation where I REALLY wish JS would take after Python.

Collapse
 
samanthaming profile image
Samantha Ming

I'm not familiar with Python -- is it more concise?

Collapse
 
jmurray90 profile image
Jake Murray

Python has an awesome title() method that will capitalize the first letter of every word in a string while lower casing the others.

Collapse
 
papagoat profile image
Terence Lucas Yap

Another great post as usual. 👍

Collapse
 
samanthaming profile image
Samantha Ming

Thanks! 😄