I have been building a React app that uses iteration a lot. I am using JSLint and get the annoying warning saying:
Don't make functions within a loop
On the following loop:
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);
}
}
I don't think I set a function in the loop? I am using the array.some function which will break the loop if I return true, which is what I do. I return a variable, declared outside of the loop, as true. This breaks me out of the loop, and allows me to do logic below.
I should also be noted that this is also entirely within a loop, as we are iterating over current search users. I get no runtime or compile errors, and this code works fine, but maybe I am setting myself up for disaster in the future.
Any ideas why I am getting this error? And if I am missing some best practice?
Since in the first line you reference currentSearch[i]
, because the [i]
I assume the whole block of code you pasted here is inside some kind of loop, probably a for
.
Then, you are creating a function for the Array.some
callback, which triggers the error.
One solution would be to move that callback declaration to be outside the parent loop, but since you are using a variable from the scope, it will require some refactor.
Posible solution
You can declare a function outside the parent loop (the one outside the code you provided here) that checks for the child user.
//Please provide a better name for the function according to the context.
const checkChildUser = function (childUser) {
return this.id === childUser.id;
};
And then pass it to the Array.some
function you are using:
currentSearch[i].users.some(checkChildUser, user);
I'm not familiar with React, but this looks like an ES6 arrow function:
childUser => { ... }
Which would be the equivalent of
function (childUser) { ... }
Well, you are providing a function in your .some()
as a parameter so thats what triggers the warning.
The reason ESLint warns against it
Writing functions within loops tends to result in errors due to the way the function creates a closure around the loop
- source
You can do it like this
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);
}
}
In your snippet, the Don't make functions within a loop
warning is not caused by the if statement
, but by this following anonymous function:
childUser => {
if(childUser.id === user.id) {
return matched = true;
}
}
Since you've said that the entire code is within a loop, a new instance of that anonymous function is being created for every iteration. This will affect the performance.
The problem here is that you create a function that modifies the matched
variable. This variable is declared with var
, so it's scope is the whole function, not a single loop iteration. This could lead to surprising results, since functions created in each iteration will actually refer to the same variable.
Simply using the value returned by some()
instead of changing matched
in the callback (as suggested by Yury Tarabanko) should remove the warning.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.