1

I'm sure this has been asked before, but I don't know what to search for.

So I want function to be called with a string that corresponds with the item clicked, but I want to simply add any new items to an array of strings.

var menuList = ["overview", "help", "search"];
var functionCalls = [
  function() { toggleMenu(menuList[0]); },
  function() { toggleMenu(menuList[1]); },
  function() { toggleMenu(menuList[2]); },
];

which is used like this in a loop: $("something").click(functionCalls[i])

This is what I want to do (but obviously it doesn't work):

for (var i in menuList) {

  // This does not work because the closure references 'i'
  // which, at the end, is always the index of the last element
  $("something").click(function() {
    toggleMenu(menuList[i]);
  });

  // this works, but I have to define each closure
  $("something").click(functionCalls[i]);
}

How can I create an anonymous function that accepts a value based on a variable - but doesn't retain the reference to the variable?

tsjnsn
  • 441
  • 5
  • 12
  • 1
    Don't use `for ... in` to iterate through arrays in JavaScript. Use an index variable and a simple `for` loop instead. – Pointy Jun 27 '13 at 14:56
  • There are many, many duplicates of this question. It's an extremely common pitfall in JavaScript. – Pointy Jun 27 '13 at 14:58
  • Which is why I noted that I'm sure it has been asked before. I'm just not familiar enough with JS to know how to deal with it properly, or what to search for. – tsjnsn Jun 27 '13 at 15:03
  • Don't feel bad - I didn't mean to criticize. It can be hard to find the duplicates because the same basic issue manifests itself in many different ways. It boils down to the fact that JavaScript scoping is only at the function level, so tricks like what Sirko posted are necessary. – Pointy Jun 27 '13 at 15:11

1 Answers1

3

You could use an IIFE like this:

for (var i=0; i<menuList.length; i++) {
  !function( index ) {
    $("something").click(function() {
      toggleMenu( menuList[index] ); 
    });
  }( i );
}

By calling the anonymous function, you create a local copy of the current value for i with the name index. Hence, all handlers receive their respective version of i.

Sirko
  • 72,589
  • 19
  • 149
  • 183