Почему оператор If считается функцией в этом цикле? - PullRequest
0 голосов
/ 19 октября 2018

Я создавал приложение React, которое часто использует итерации.Я использую JSLint и получаю досадное предупреждение:

Не выполнять функции в цикле

В следующем цикле:

if(currentSearch[i].users.length > 0) {
    var matched = false;

    //I hate how JSLint just can't handle setting a variable to true within a function
    //this is loop where I get the warning 
    currentSearch[i].users.some(childUser => {
        if(childUser.id === user.id) {
            return matched = true;
        }
    })
    //^^^^^ Warning

    if(!matched) {
        var alert = new AlertObject(user,currentSearch[i],true,false);
        alerts.push(alert);
    }
}

Я не думаю, что я установил функцию в цикле?Я использую функцию array.some, которая прервет цикл, если я верну true, что я и делаю.Я возвращаю переменную, объявленную вне цикла, как true.Это вырывает меня из цикла и позволяет мне выполнять логику ниже.

Я также должен отметить, что это также полностью внутри цикла, поскольку мы выполняем итерации для текущих пользователей поиска.Я не получаю ошибок времени выполнения или компиляции, и этот код работает нормально, но, возможно, я настраиваю себя на случай катастрофы в будущем.

Есть идеи, почему я получаю эту ошибку?А если мне не хватает лучшей практики?

Ответы [ 5 ]

0 голосов
/ 19 октября 2018

Проблема в том, что вы создаете функцию, которая изменяет переменную matched.Эта переменная объявлена ​​с var, так что ее область действия - целая функция, а не итерация одного цикла.Это может привести к неожиданным результатам, поскольку функции, созданные в каждой итерации, на самом деле будут ссылаться на одну и ту же переменную.

Просто использовать значение, возвращаемое some() вместо изменения matched вобратный вызов (как предложил Юрий Тарабанко) должен убрать предупреждение.

0 голосов
/ 19 октября 2018

В вашем фрагменте предупреждение Don't make functions within a loop вызвано не if statement, а следующей анонимной функцией:

childUser => {
 if(childUser.id === user.id) {
  return matched = true;
 }
}

Поскольку вы сказали, что весь код находится в цикледля каждой итерации создается новый экземпляр этой анонимной функции.Это повлияет на производительность.

0 голосов
/ 19 октября 2018

Поскольку в первой строке вы ссылаетесь на currentSearch[i], потому что [i] Я предполагаю, что весь блок кода, который вы вставили здесь, находится внутри какого-то цикла, вероятно, for.

Тогда,вы создаете функцию для обратного вызова Array.some, которая вызывает ошибку.

Одним из решений было бы переместить это объявление обратного вызова за пределы родительского цикла, но поскольку вы используете переменную из области видимости,это потребует некоторого рефакторинга.


Возможное решение

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

//Please provide a better name for the function according to the context.
const checkChildUser = function (childUser) {
    return this.id === childUser.id;
};

А затем передайте его функции Array.some, которую вы используете:

currentSearch[i].users.some(checkChildUser, user);
0 голосов
/ 19 октября 2018

Ну, вы предоставляете функцию в вашем .some() в качестве параметра, так что именно это вызывает предупреждение.

Причина, по которой ESLint предупреждает об этом

Writing functions within loops tends to result in errors due to the way the function creates a closure around the loop - источник

Вы можете сделать это так

function compareId(childUser) {
  if (childUser.id === user.id) {
    return true;
  }
}

if (currentSearch[i].users.length > 0) {
  var matched = currentSearch[i].users.some(compareId);

  if (!matched) {
    var alert = new AlertObject(user, currentSearch[i], true, false);
    alerts.push(alert);
  }
}
0 голосов
/ 19 октября 2018

Я не знаком с React, но это похоже на функцию стрелки ES6:

childUser => { ... }

Что было бы эквивалентно

function (childUser) { ... }
...