JavaScript - моя функция срабатывает только один раз при вызове несколько раз в цикле - PullRequest
0 голосов
/ 22 февраля 2019

У меня есть эта функция:

  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);
 }

Переменная Objects содержит массив элементов.

Консоль покажет мне только внутренний текст первого элемента, а i покажет длинумоего массива - 1.

Если я удалю цикл своей функции, консоль покажет мне внутренний текст каждого объекта и правильную серию чисел.

Я не совсем понимаю этоповедение, любая помощь?

Ответы [ 2 ]

0 голосов
/ 22 февраля 2019

Проблема в том, как ограничены ваши счетчики циклов.Вместо того, чтобы делать

for (i = 0; ...)

Вы должны объявить свой счетчик цикла как

for (let i = 0;...)

, чтобы он был ограничен вашим блоком цикла.

Если вы объявляете переменную циклатак как просто «i = 0», то «i» имеет глобальную область видимости.В этом сценарии «i», которое вы используете в цикле simpifyString, - это то же «i», которое вы используете в цикле, который вызывает simpifyString!Так как simpleifyString увеличивает 'i' после того, как вы вызываете его в первый раз, цикл вызова преждевременно завершается.

0 голосов
/ 22 февраля 2019
for (i = 0; i < objects.length; i++)
for (i = 0; i < charsToFind.length; i++)

TO ...

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, поэтомуприсваивается тому же свойству i в глобальном объекте , а не объявляется новой переменной локальной области.Цикл for внутри simplifyString (string) присваивает новое значение тому же i, что и первый for цикл, и все портит.


* Как уже упоминалось в комментариях, это то, как выможно использовать 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);
}

ПРИМЕЧАНИЕ. Если вы работаете с большими наборами данных, я бы спросил кого-нибудь умнее меня, как сделать это с несколькими строками регулярных выражений, что будет гораздо эффективнее, чем перебирать заменители

...