我正在尝试在 javascript 中为数字 1 到 9 设置一些键绑定,然后单击页面上标记为“show1”、“show2”等的各种链接。
问题是它为数字创建了键绑定,但它总是显示最后一项,即:'show9'。
这是一个示例,如果您在键盘上按 1 或 2,函数将返回 3,而它应该分别返回 1 和 2。
for i in [1..2]
key i.toString(), (e) ->
alert i
我正在尝试在 javascript 中为数字 1 到 9 设置一些键绑定,然后单击页面上标记为“show1”、“show2”等的各种链接。
问题是它为数字创建了键绑定,但它总是显示最后一项,即:'show9'。
这是一个示例,如果您在键盘上按 1 或 2,函数将返回 3,而它应该分别返回 1 和 2。
for i in [1..2]
key i.toString(), (e) ->
alert i
您正在创建的函数具有对变量的持久引用i
,而不是创建函数时的副本,这就是为什么您总是看到它的最终值 ( 3
)。
更新:答案末尾有一种更类似于 CoffeeScript 的方式,尽管阅读整个内容很有用,以便您了解权衡取舍。
相反,使用一个构建器函数来创建关闭不同变量的函数,一个不会改变的:更新的小提琴
buildHandler = (value) ->
(e) ->
alert value
return
for i in [1..2]
key i.toString(), buildHandler i
在那里,我们的处理函数关闭了我们传递的参数buildHandler
,所以它不会改变。
更多:闭包并不复杂(但基于 JavaScript,而不是 CoffeeScript)
对于那些真正喜欢立即调用函数表达式 (IIFE) 的人(我不推荐循环中的 IIFE,理论上它每次都会创建一个新函数只是为了把它扔掉,而且很难阅读):
for i in [1..2]
key i.toString(), (
(value) ->
(e) ->
alert value
return
)(i)
mu is too short在评论中指出 CoffeeScript 有一个关键字可以做到这一点:它在文档本节do
的末尾附近。使用它看起来像这样:
for i in [1..2]
key i.toString(), do (i) -> (e) ->
alert i
return
现在,它被转换为创建不必要的函数并将它们丢弃的 JavaScript(就像上面的 IIFE 所做的那样),但对于许多用例来说,这可能并不重要。我仍然可能会为了上面的第一个选项的清晰性而努力,但是带上很多工具是件好事。