JSLint and JSHint will throw the "Don't make functions within a loop" error when they encounter a function statement or expression within a for, while or do statement. In the following example we attempt to add a click event listener to each element with a given class name. The event handler is intended to overwrite the contents of the clicked element with the value of i at a specific iteration of the loop:
This error is raised to highlight a piece of code that may not work as you expect it to and could also indicate a misunderstanding of how the language works. Your code may run without any problems if you do not fix this error, but in some situations it could behave unexpectedly.
In the example above, when you click on one of the affected elements and trigger the event handler, the content will change to the final value of i. If there are 4 elements in the NodeList referred to by elems, the content of each element will end up being "4".
To work around this, we need to capture the value of i at each iteration of the loop and ensure that it's that value that is referred to by the click event handler bound at this iteration. A common solution is to wrap the body of the loop in an immediately invoked function expression (IIFE), creating a closure that captures the value of the variable:
This will work as we expect it to, with each element getting the correct value of i, but it's definitely starting to look messy and becoming harder to read (and therefore harder to maintain). And in any case, since there's still a function within the loop, JSLint and JSHint will still complain. To fix the issue, we need to move the function out of the loop, and maintain the closure:
In JSHint 1.0.0 and above you have the ability to ignore any warning with a special option syntax. The identifier of this warning is W083. This means you can tell JSHint to not issue this warning with the
/*jshint -W083 */ directive.