Reputation: 401
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
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(" "));
Upvotes: 2
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
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