0

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

     function onMouseIn(e){
      // Do stuff
     }

     function onMouseOut(e){
      // 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. I also want to pass the event and the jquery object. So my code becomes something like this

 function onMouseIn(e,btn){
  // Do stuff using arg
 }

 function onMouseOut(e,btn){
  // Do stuff using arg
 }

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

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?

2 Answers2

1

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")

Jonathan Lonowski
  • 121,453
  • 34
  • 200
  • 199
0

You can use bind here

change the code to the following

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(onMouseIn.bind(null,"arg"),onMouseOut.bind(null,"arg"));
 }

Hope it helps

Geeky
  • 7,420
  • 2
  • 24
  • 50