User 18473564 User 18473564 - 8 months ago 38
jQuery Question

Passing arguments to named function jshint warning

I have to use external/named functions for hover, like this:

function onMouseIn(){
// Do stuff
}

function onMouseOut(){
// Do stuff
}

for (var btn_index = 0; btn_index < 3; btn_index++) {
btn.hover(onMouseIn,onMouseOut)
}


However i also need to pass arguments to the functions, so i figured out i'd use unnamed functions for mouseIn and mouseOut events and call my named functions onMouseIn and onMouseOut repectively with the arguments i want. So my code becomes something like this

function onMouseIn(arg){
// Do stuff using arg
}

function onMouseOut(arg){
// Do stuff using arg
}

for (var btn_index = 0; btn_index < 3; btn_index++) {
btn.hover(function() {onMouseIn("arg")},function() {onMouseOut("arg")})
}


But then jshint give me this warning


Don't make functions within a loop.


So are there any other ways to pass arguments to named functions? If not then how can i make jshint to hide the warning?

Answer Source

The warning is suggesting to try preparing the functions outside of the loop, if possible, so they can be reused throughout the loop:

// ...onMouseIn & onMouseOut...

function onHoverStart() {
  onMouseIn("arg");
}

function onHoverStop() {
  onMouseOut("arg");
}

for (var btn_index = 0; btn_index < 3; btn_index++) {
  btn.hover(onHoverStart, onHoverStop);
}

When using function expressions within the loop (at least, when closures aren't needed), each iteration creates 2 new Function objects, with each pair a duplicate of the first. JSHint flags it as potentially wasteful.


Based on your comment, if one of the argument you need to provide is the iterator, btn_index, you can do that by modifying onHoverStart and onHoverStop to be called and used as closures for each event.

// ...onMouseIn & onMouseOut...

function onHoverStart(index) { // closure for index
  return function (event) {    // enclosed event handler
    onMouseIn("arg", index, event); // revise the argument order here as needed
  };
}

function onHoverStop(index) {
  return function (event) {
    onMouseOut("arg", index, event);
  };
}

for (var btn_index = 0; btn_index < 3; btn_index++) {
  btn.hover(onHoverStart(btn_index), onHoverStop(btn_index));
}

(For more details on closures, see "How do JavaScript closures work?" and "JavaScript closure inside loops – simple practical example")