8

Possible Duplicate:
How do JavaScript closures work?

I've read all the million duplicates of the same old javascript closure loop issue. I thought I understood them, and have been using closures for months without issue, until today. I am stumped.

for (var i in groups){
    for(var j in groups[i]){
        $(unique_form).die('submit').live('submit'), function{
             function (groups2, i2, j2){
                 return function(){alert(groups2[i2][j2])}
              }(groups, i, j)
             }
         });
        }               
    }
 }

When I submit each unique form - I keep getting an alert for the last element of groups[i][j]. Obviously, I'm doing something stupid, what is it? I thought that by creating the anonymous function groups2, i2, and j2 I was solving the problem.

Community
  • 1
  • 1
George B
  • 2,592
  • 3
  • 22
  • 27

3 Answers3

8

The function you pass to .live() is executed when the submit event is fired. By that point, i and j will have their final values. You would need to create the closure outside of the event handler:

(function (i2, j2) {
    $(unique_form).die('submit').live('submit', function{
        alert(groups[i2][j2])
    });
}(i, j));

Notice that I've removed the groups argument from the anonymous function. There's no need to close over that since its value won't change. I've also wrapped the entire function expression in parentheses, which is the convention (and in this case actually required, to force it to be parsed as an expression).

Also note that I've removed the closing parentheses that you have after the first argument to .live() in your question. It shouldn't be there.


Side note.

.live() and .die() have been deprecated for ages now. Use .on() (with jQuery 1.7+) or .delegate() (with older versions).

James Allardice
  • 164,175
  • 21
  • 332
  • 312
  • +1 don't forget to remove that erroneous parentheses `live('submit')` <-- – wirey00 Jan 16 '13 at 21:55
  • Thank you very, very, very much. You explained exactly why my code was not working and you offered a working solution. I really appreciate it. – George B Jan 16 '13 at 22:11
0

Your code sets up groups.length squared live submit handlers. Each live handler consists of a different copy of this function:

function{
    function (groups2, i2, j2){
        return function(){alert(groups2[i2][j2])}
    }(groups, i, j)
}

When the submit event happens, all of the live handlers file, each referencing the last value of i and j.

It's hard to say what you truly want based on the code fragment, with more info I could probably help more. Good luck!

jimbo
  • 11,004
  • 6
  • 29
  • 46
-1

Try this out

for (var i in groups){
    for(var j in groups[i]){
        $(unique_form).die('submit').live('submit', function( groups2, i2, j2 ){
             return function (){
                 alert(groups2[i2][j2])
             }
         }(groups, i, j) );
        }               
    }
 }
Theodosis
  • 31
  • 6