繁体   English   中英

JavaScript-我的函数在一次循环中被调用多次时仅触发一次

[英]JavaScript - My function only triggers once while being called several times in a loop

我有这个功能:

  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。

如果删除函数的循环,控制台将向我显示每个对象的内部文本以及正确的数字序列。

我不太了解这种行为,有什么帮助吗?

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

当前,您在两个for循环中都声明了i ,但没有标识符var, let, const因此将其分配给全局对象的相同i属性,而不是声明新的局部范围的变量。 simplifyString (string)内部的for循环将一个新值分配给与第一个for循环相同的i ,并破坏所有内容。


*如评论中所述,这是如何使用reduce()使代码更具可读性,最大程度地减少不必要的副作用/变异以及将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);
}

注意:如果要在大型数据集上运行,我会问一个比我聪明的人,用几行正则表达式来做到这一点,这比遍历替换项要高效得多

问题在于循环计数器的范围如何。 而不是做

for (i = 0; ...)

您应该将循环计数器声明为

for (let i = 0;...)

因此,它的作用域是您的循环块。

如果将循环变量声明为“ i = 0”,则“ i”具有全局作用域。 在这种情况下,您在simpleString循环中使用的“ i”与在调用simpleString的循环中使用的“ i”相同! 由于simpleString在您首次调用后会递增“ i”,因此调用循环会提前终止。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM