The function you're creating has an enduring reference to the i
variable, not a copy of it as of when the function was created, which is why you always see its final value (3
).
Update: There's a more CoffeeScript-ish way at the end of the answer, although it's useful to read the whole thing so you understand the trade-offs.
Instead, use a builder function that creates functions that close over a different variable, one that doesn't change: Updated Fiddle
buildHandler = (value) ->
(e) ->
alert value
return
for i in [1..2]
key i.toString(), buildHandler i
There, our handler function closes over the argument we pass buildHandler
, and so it doesn't change.
More: Closures are not complicated (but based on JavaScript, not CoffeeScript)
And for those who really like immediately-invoked function expressions (IIFEs) (I don't recommend IIFEs in loops, in theory it creates a new function every time just to throw it away, and it's hard to read):
for i in [1..2]
key i.toString(), (
(value) ->
(e) ->
alert value
return
)(i)
mu is too short points out in the comments that CoffeeScript has a keyword for doing exactly this: do
It's near the end of this section of the documentation. Using it for this would look like this:
for i in [1..2]
key i.toString(), do (i) -> (e) ->
alert i
return
Now, that gets translated to JavaScript that creates unnecessary functions and throws them away (like the IIFE above does), but for a number of use cases it probably doesn't matter. I'd still probably go for the clarity of my first option above, but it's good to have lots of tools in the belt.