CoffeeScript动态方法

时间:2011-06-28 15:08:28

标签: metaprogramming coffeescript

我正在尝试在咖啡脚本中动态创建方法,但正如我的代码所示,我用来创建方法的迭代器不会在迭代之间重置其变量,所以我想知道冲突的共享变量:

class MyClass
  constructor: (@name) ->

  for k, v of ['get', 'set']
    console.log('creating method: ' + v)
    MyClass::[v] = (args...) ->
      method = v
      console.log('executing method: ' + method)

o = new MyClass('dummy')
o.get()
o.set()

输出:

> creating method: get
> creating method: set
> executing method: set
> executing method: set

我知道我做错了什么?

2 个答案:

答案 0 :(得分:7)

mu已正确诊断出该问题。最直接的解决方案是使用CoffeeScript语言的do关键字,该关键字创建并运行一个内部函数,用于捕获传入的变量的值:

for k, v of ['get', 'set']
  do (k, v) ->
    console.log('creating method: ' + v)
    MyClass::[v] = (args...) ->
      method = v
      console.log('executing method: ' + method)

我在PragPub文章A CoffeeScript Intervention中讨论了这个功能。

答案 1 :(得分:5)

你的内心功能:

(args...) ->
  method = v
  console.log('executing method: ' + method)

实际上是v上的一个闭包,所以当它被执行时,v将评估它在循环中的最后一个值(即set)。看起来你只需要一点关闭破坏:

build_method = (v) ->
  (args...) ->
    method = v
    console.log('executing method: ' + method)

然后:

for k, v of ['get', 'set']
  console.log('creating method: ' + v)
  MyClass::[v] = build_method(v)

请记住,CoffeeScript只是具有不同构成的JavaScript,因此它遇到了许多相同的问题(与任何带闭包的语言一样),并且这些问题具有相同的解决方案。