Arnaud Stephan
Arnaud Stephan

Reputation: 401

Capitalize the first letter of each word using

I'm doing a class on javascript this semester, and one of this week's exercises was to take a string of words, and capitalize the first letter of each word. I did that using .map(), the code is here :

let t1 = "hello how are you doing".split(" ");

let t2 = t1.map(function(word) {
  return word[0].toUpperCase() + word.slice(1);
});
console.log(t2.join(" "));

And it works perfectly fine. However, I was wondering why, when I try with forEach(), I can't make it work. Here is my code :

let t1 = "hello how are you doing".split(" ");


t1.forEach(function(word) {
  word[0] = word[0].toUpperCase();
})
console.log(t1.join(" "));

My understanding of forEach() is that it cycles through every element of the table, much like a simple for loop. So then shouldn't my code take the first letter of each word, and replace it with the same letter, to which toUpperCase() is applied?

edit : I already know how to capitalize the first letter of each word, I was just asking about the different methods

Upvotes: 0

Views: 344

Answers (3)

Rajesh
Rajesh

Reputation: 24955

First, string in JS is immutable.

var str = 'hello World';
str[0] = 'H';
console.log(str)

So word[0] = will not have any effect.

Second, even if it was, you are updating a value of an argument variable and not value in array.

var a = [1, 2, 3];

a.forEach(function(n) {
  n = n * 2;
});

console.log(a)

As per discussion with @deceze, this point is not accurate.

If a string was mutable, that would have worked just fine. Your "Second" doesn't really apply. – deceze


@deceze Objects are assigned using reference, so it will have the effect. Primitive values are assigned using value. So n in my understanding will always be a copy of item in array. Any manipulation relating to it should not affect the item in array. And string being a primitive value, I mentioned it. Also, I can't think of any variable that has property and is of primitive type. If you have any idea please let me know. Would be glad to learn. :-) – Rajesh


Sure, you're right about that. That's why I'm saying if it was mutable in the first place… Since it's not, the point is moot either way. – deceze


To get the desired effect, you will have to override value in array.

let t1 = "hello how are you doing".split(" ");


t1.forEach(function(word, index) {
  t1[index] = word[0].toUpperCase() + word.substring(1);
})
console.log(t1.join(" "));

Reference:

Upvotes: 2

deceze
deceze

Reputation: 522513

let word = 'foo';
word[0] = 'F';
console.log(word);

The modification of word doesn't take because strings are immutable. You can't change a single character inside a string.

For character access using bracket notation, attempting to delete or assign a value to these properties will not succeed. The properties involved are neither writable nor configurable.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String

Upvotes: 2

gurvinder372
gurvinder372

Reputation: 68433

So then shouldn't my code take the first letter of each word, and replace it with the same letter, to which toUpperCase() is applied?

Because word is a primitive value hence when you set new value to word, it doesn't carry the reference back to the array.

However, if parameter of forEach is not a primitive value, then the original one gets mutated, see the demo below

var arr = [[1,2,3],[4,5,6],[7,8,9]];
arr.forEach(function(item){
  item.push(1);
})
console.log(arr);

Upvotes: 1

Related Questions