【问题标题】:Extending a CoffeeScript class dynamically动态扩展 CoffeeScript 类
【发布时间】:2013-04-07 06:52:42
【问题描述】:

我知道 CoffeeScript 类可以这样扩展:

Dog::bark = ->
  console.log("bark")

我希望能够动态地做到这一点。例如,我想做这样的事情:

sounds = [ "bark", "woof", "grrr", "ruff" ] 

for sound in sounds
  Dog::[sound] = ->
    console.log(sound)

等效的 JavaScript 是:

var sounds = [ "bark", "woof", "grrr", "ruff" ];

for (var i = 0; i < sounds.length; i++) 
{
  var sound = sounds[i];

  Dog.prototype[sound] = function() {
    console.log(sound);
  };
}

如何使用 CoffeeScript 做到这一点?

【问题讨论】:

    标签: coffeescript


    【解决方案1】:

    您几乎拥有它,您只需在其中扔一个do 以强制在您构建新方法时评估sound

    sounds = [ "bark", "woof", "grrr", "ruff" ] 
    for sound in sounds
        do (sound) ->
            Dog::[sound] = -> console.log(sound)
    

    如果您不包含do,您最终将使用console.log('ruff') 的所有四种方法。添加dofor 循环体转换为自执行函数。来自fine manual(部分底部):

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

    演示:http://jsfiddle.net/ambiguous/YAqJu/

    【讨论】:

    • Dog::[sound] 真的是正确的语法吗?我只是猜测。
    • @LandonSchropp:是的。 :: 只是 prototype[sound] 是一个普通的对象属性引用。所以Dog::[sound]Dog.prototype[sound] 相同,这就是您要添加的方法。
    • 闭包包装也不错。我什至没有考虑过。
    • 太棒了。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-20
    • 2012-05-15
    • 2016-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-14
    相关资源
    最近更新 更多