我有这个功能:
function simplifyString (string)
{
var charsToFind = new Array(/[áàâãä]/g, /[éèêë]/g, /[íìîï]/g, /[óòôõö]/g, /[úùûü]/g, /ç/g, /[- \'&_]/g),
charsToReplace = new Array('a', 'e', 'i', 'o', 'u', 'c', '');
string = string.toLowerCase();
for (i = 0; i < charsToFind.length; i++)
{
string = string.replace(charsToFind[i], charsToReplace[i]);
}
return string;
}
然后在循环中使用它,就像这样:
for (i = 0; i < objects.length; i++)
{
var value = simplifyString(objects[i].innerText);
console.log(value);
console.log(i);
}
对象变量包含一个元素数组。
控制台仅显示第一个元素的内部文本,i
将显示我数组的长度-1。
如果删除函数循环,控制台将向我显示每个对象的内部文本以及正确的数字序列。
我不太了解这种行为,有什么帮助吗?
答案 0 :(得分:1)
for (i = 0; i < objects.length; i++)
for (i = 0; i < charsToFind.length; i++)
去...
for (var i = 0; i < objects.length; i++)
for (var i = 0; i < charsToFind.length; i++)
或...
for (let i = 0; i < objects.length; i++)
for (let i = 0; i < charsToFind.length; i++)
关于浏览器支持的注意事项:在IE 11中,“让变量没有分别绑定到for循环的每次迭代中” Caniuse - let。
您当前正在两个i
循环中声明for
,但没有标识符var, let, const
,因此已将其分配给{{3}上的相同i
属性},而不是声明新的局部范围的变量。 for
内的simplifyString (string)
循环正在为与第一个i
循环相同的for
分配一个新值,并破坏了所有内容。
*如评论中所述,这是您如何使用reduce()
来使代码更具可读性,最小化不必要的global object并将您的tests
与替换values
直接耦合的一种方法混乱...
var charReplacements = [
{ test: /[áàâãä]/g, value: 'a' },
{ test: /[éèêë]/g, value: 'e' },
{ test: /[íìîï]/g, value: 'i' },
{ test: /[óòôõö]/g, value: 'o' },
{ test: /[úùûü]/g, value: 'u' },
{ test: /ç/g, value: 'c' },
{ test: /[- \'&_]/g, value: '' }
];
function simplifyString (string) {
return charReplacements
.reduce((str, {test, value}) =>
str.replace(test, value)
, string);
}
注意:如果要在大型数据集上运行,我会问比我聪明的人如何用几行正则表达式来做到这一点,这比遍历替换项要高效得多
答案 1 :(得分:1)
问题在于循环计数器的范围如何。 而不是
for (i = 0; ...)
您应将循环计数器声明为
for (let i = 0;...)
因此它的作用域仅限于您的循环块。
如果将循环变量声明为“ i = 0”,则“ i”具有全局作用域。在这种情况下,您在simpleString循环中使用的“ i”与在调用simpleString的循环中使用的“ i”相同!由于simpleString在您首次调用后会递增“ i”,因此调用循环会提前终止。