我看不到为什么下面的第一个代码(titleCase1)不能大写,而第二个代码却大写(titleCase2)。
var result1 = titleCase1('this is a new question in stackoverflow');
console.log('result1:',result1);
var result2 = titleCase2('this is a new question in stackoverflow');
console.log('result2:',result2);
function titleCase1(str) {
let words = str.split(" ");
for (let word of words) {
word = word[0].toUpperCase() + word.slice(1);
}
return words.join(" ");
}
function titleCase2(str) {
let words = str.split(" ");
for (let i = 0; i < words.length; i++) {
words[i] = words[i][0].toUpperCase() + words[i].slice(1);
}
return words.join(" ");
}
似乎在第一种情况下,words
数组未更新,并且与let element of array
迭代器有关,但是我不明白为什么它不起作用。
答案 0 :(得分:1)
与JavaScript中的数组不同,字符串是值对象,而不是引用对象。
这里:
for (let word of words) {
word = word[0].toUpperCase() + word.slice(1);
}
您正在使用let
声明一个单词变量,它的作用域为for循环。此变量是字符串中子字符串的副本。您可以在每次迭代时重新分配它,但是由于它是一个副本而不是对子字符串的引用,因此数组words
中的子字符串不会更改,只有副本会更改。
但是这里:
for (let i = 0; i < words.length; i++) {
words[i] = words[i][0].toUpperCase() + words[i].slice(1);
}
您正在直接更改子字符串,因为您是通过在子字符串数组中建立索引来更新每个字符的。
这是使用String.replace
,正则表达式和箭头函数的一种更短的方法:
const titleCase = str => str.replace(/(?<=(\s+|^))\w/gi, x => x.toUpperCase());
console.log(titleCase('hello world'));
console.log(titleCase(' hello world'));
正则表达式(?<=(\s+|^))
后面是一个正数,并确保模式\w
(单词字符)前面有空格或位于字符串的开头。
答案 1 :(得分:0)
在第一个代码中,您正在重新分配变量。至少在99%的情况下,重新分配变量本身永远不会对其他任何事物产生任何影响;这仅意味着word
块中对for
的进一步引用将引用新值,而不是旧值。因此,您的word = ...
不会有任何影响,因为您稍后在代码块中不会使用新的word
变量名进行任何操作。 (在该迭代结束之后,存储在其中的值将被取消引用,并很快将被GC处理)
在第二个代码中,您正在变异一个对象:words[i] =
意味着对i
的索引words
的进一步访问将返回新值
答案 2 :(得分:0)
word不是数组。这只是一个字。并且您返回的单词已经加入它们,而这些单词已经是没有空格的字符串,将无效
function titleCase(str) {
let a=[];
let words = str.split("");
for (let word of words) {
a.push(word.toUpperCase());
}
return a.join("");
}
console.log(titleCase("hello"))