Coffeescript - 如何应用闭包和匿名函数

时间:2016-05-13 15:05:14

标签: reactjs coffeescript react-rails

我试图将for循环变量作为参数传递给coffeescript中的onclick方法,如下所示:

for index, option_value of @state.option_values
                  dom.span
                    key: "#{index} #{option_value.name}"
                    className: "pull-left col-md-3#{if option_value.selected then ' selected' else ''}"
                    onClick: () => @selectThis option_value


selectThis: (option_value_selected) ->
    alert(option_value_selected.name)

option_value始终引用option_value@state.option_values的最后一个值。我知道如何在普通的JavaScript中解决这个问题。但是,如何在咖啡中解决这个问题?

2 个答案:

答案 0 :(得分:2)

问题在于你的功能:

onClick: () => @selectThis option_value

只是存储option_value引用,直到稍后调用onClick处理程序时才会对其进行求值。

这是JavaScript和CoffeeScript中循环的一个非常常见的问题,解决方案始终是相同的:强制在创建匿名函数时评估变量。您的:

@selectThis.bind(null, option_value)

通过调用Function.prototype.bind函数来做到这一点(但是在调用函数时@将是null,所以要小心。)

JavaScript中常见的习惯用法是将循环体转换为自调用函数:

for(i = 0; i < 6; ++i)
    (function(i) { ... })(i)

强制在每次迭代时计算循环变量。 CoffeeScript有do loops作为这个习语的捷径:

  

当使用JavaScript循环生成函数时,通常会插入一个闭包装,以确保循环变量被关闭,并且所有生成的函数不只是共享最终值。 CoffeeScript提供do关键字,它立即调用传递的函数,转发任何参数。

惯用的CoffeeScript解决方案如下所示:

for index, option_value of @state.option_values
  do (index, option_value) =>
    dom.span
      key: "#{index} #{option_value.name}"
      className: "pull-left col-md-3#{if option_value.selected then ' selected' else ''}"
      onClick: => @selectThis option_value

答案 1 :(得分:1)

终于找到了正确的语法,感叹:

onClick: @selectThis.bind(null, option_value)