4

I am doing a simple function. To turn all words first-letter to upper case, but It simply doesn't work, neither display any errors:

function formatTitle(input) {
  var words = input.split(' ');
  for (var i = 0; i < words.length; i++) {
    words[i][0] = words[i][0].toUpperCase();
  };
  return words.join(' ');
};

var newTitle = formatTitle("all words first-letter should be upper case");

document.write(newTitle);

Thanks in advance.

Tushar
  • 85,780
  • 21
  • 159
  • 179

3 Answers3

9

The problem is that strings in javascript are immutable. You can't just change a char like this.

A solution would be this:

words[i] = words[i][0].toUpperCase()+words[i].slice(1);

But you could have a simpler and faster code using a regular expression:

return input.replace(/\b\w/g,function(b){ return b.toUpperCase() })

(here with a more complete uppercasing, not just after spaces - if you want to stick to spaces use replace(/(\s+|^)\w/g,function(b){ return b.toUpperCase() }))

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • I'll go with the first approach. Using `regex` is bit slower than `string` methods – Tushar Jul 23 '15 at 12:45
  • 1
    "Using regex is bit slower" ? Most of the times using a regex is a bigger improvement in performances compared to string and array manipulations (maybe not here due to function calling, we'd need to test, unfortunately jsperf.com is down). – Denys Séguret Jul 23 '15 at 12:46
  • 1
    @Tushar I verified: using a regex here, even the complex one, is much faster http://jsbin.com/zohikoxubo/1/edit?js,output – Denys Séguret Jul 23 '15 at 13:06
  • You can also “prove” that strings are immutable with `Object.getOwnPropertyDescriptor(words[i],0).writable == false`. – Sebastian Simon Jul 23 '15 at 13:36
6

Problem

Because

words[i][0] = 'something'

does not update the words[i].

Problem Demo

var myVar = 'abc';

myVar[0] = 'd';

document.write(myVar); // abc

Solution

You can use substr to get the first character and update the value of whole string.

Solution Demo

function formatTitle(input) {
  var words = input.split(' ');
  for (var i = 0; i < words.length; i++) {
    words[i] = words[i].substr(0, 1).toUpperCase() + words[i].substr(1);
  }
  return words.join(' ');
}

var newTitle = formatTitle("all words first-letter should be upper case");

document.write(newTitle);
Tushar
  • 85,780
  • 21
  • 159
  • 179
0

How wrote Denis the reason is that strings in javascript are immutable (numbers and booleans are also immutable).

Another very simple solution for Upperize the first char of a string is:

function firstUpper(word) {
     return word.charAt(0).toUpperCase() + word.substring(1);
};

I suggest also to read this post: Understanding Javascript immutable variable

Hope this help

Community
  • 1
  • 1
appersiano
  • 2,670
  • 22
  • 42