How to Fix Jslint Error 'Don't Make Functions Within a Loop.'

Don't make functions within a loop

Move the function outside the loop:

function dummy() {
return this.name_;
}
// Or: var dummy = function() {return this.name;};
for (var i = 0; i<processorList.length; ++i) {
result[i] = {
processor_: timestampsToDateTime(processorList[i]),
name_: processorList[i].processorName,
getLabel: dummy
};
}

... Or just ignore the message by using the loopfunc option at the top of the file:

/*jshint loopfunc:true */

Getting warning don't make functions within a loop jslint

In that specific case, you could ignore the warning, because your functions don't use any variables they close over (like i) that change in the course of the loop.

But since they don't, there's no reason to create several copies of the function when just one will do:

function squareClick() {
'use strict';
var selectedColor = (this.style.background);
if (selectedColor === pickedColor) {
console.log("True");
} else {
console.log('False');
}
}

for (i = 0; i < square.length; i++) {
//add different color to square
square[i].style.background = colors[i];
//add eventlistner to square
square[i].addEventListener('click', squareClick);
}

Where it would be a problem:

Suppose you did this and there were 8 squares:

for (i = 0; i < square.length; i++) {
square[i].addEventListener('click', function() {
alert(i); // <=== Using i
});
}

When you clicked those squares, you'd see the value 8, no matter which square you clicked, because those functions have a live reference to the i variable, not a copy of the variable as of when they were created.

That's part of why jsLint warns you about this: Either you need to be careful (because you're using i), or it's pointless to create functions in the loop (because you aren't using anything that varies).

Final note: In ES2015, you could safely do this:

for (let n = 0; n < square.length; n++) {
square[n].addEventListener('click', function() {
alert(n); // <=== Using n
});
}

...and you'd see 0, 1, 2, ... 7 depending on what square you clicked. This is because the ES2015+ semantics of the let declarations within for loops is specifically designed to ensure that each loop iteration gets its own copy of n. This is very different from the seemingly-near-identical version using var.

Example with var; they all show 8:

var square = document.querySelectorAll(".square");for (var i = 0; i < square.length; i++) {  square[i].addEventListener('click', function() {    alert(i); // <=== Using i  });}
<div class="square">zero</div><div class="square">one</div><div class="square">two</div><div class="square">three</div><div class="square">four</div><div class="square">five</div><div class="square">six</div><div class="square">seven</div>

How to fix jslint error 'Don't make functions within a loop.'?

Douglas Crockford has a new idiomatic way of achieving the above - his old technique was to use an inner function to bind the variables, but the new technique uses a function maker. See slide 74 in the slides to his "Function the Ultimate" talk. [This slideshare no longer exists]

For the lazy, here is the code:

function make_handler(div_id) {
return function () {
alert(div_id);
};
}
for (i ...) {
div_id = divs[i].id;
divs[i].onclick = make_handler(div_id);
}

How to fix JSHint Don't make functions within a loop (loopfunc rule) warning?

The warning is trying to prevent you from running into problems like JavaScript closure inside loops – simple practical example (which is so common it has about 1800 duplicates or related questions on SO alone).

Fortunately your actual code is not affected by this problem, which means we can pull the function out of the loop. This also fixes the JSHint warning:

var buttons = document.getElementsByTagName("button");
var buttonsCount = buttons.length;
var handler = function () {
console.log(this.id);
};

for (var i = 0; i < buttonsCount; i++) {
buttons[i].onclick = handler;
}

JSlint error 'Don't make functions within a loop.' leads to question about Javascript itself

Would a Javascript interpreter really create an instance of the function per iteration?

It has to because it doesn't know if the function object will be modified elsewhere. Remember that functions are standard JavaScript objects, so they can have properties like any other object. When you do this:

card = $('<div>').bind('isPopulated', function (ev) { ... })

for all you know, bind could modify the object, for example:

function bind(str, fn) {
fn.foo = str;
}

Clearly this would result in wrong behaviour if the function object was shared across all iterations.

Don't make functions within a loop error I can't fix

You'd want to move your function outside your loop:

var inputs = document.getElementsByTagName('input');
var blurInput = function () {
this.blur();
};

// (rename this to something useful...)
var doSomething = function (input) {
input.addEventListener('focus', blurInput);
};

for (var i = 0; i < inputs.length; i++) {
doSomething(inputs[i]);
}


Related Topics



Leave a reply



Submit