Reputation: 10274
I know that a CoffeeScript class can be extended like this:
Dog::bark = ->
console.log("bark")
I want to be able to do this dynamically. For example, I want to do something like this:
sounds = [ "bark", "woof", "grrr", "ruff" ]
for sound in sounds
Dog::[sound] = ->
console.log(sound)
The equivalent JavaScript would be:
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);
};
}
How can I do this with CoffeeScript?
Upvotes: 2
Views: 488
Reputation: 434985
You almost have it, you just need to toss a do
in there to force sound
to be evaluated when you build the new method:
sounds = [ "bark", "woof", "grrr", "ruff" ]
for sound in sounds
do (sound) ->
Dog::[sound] = -> console.log(sound)
If you don't include the do
you'll end up with all four methods doing console.log('ruff')
. Adding the do
converts the for
loop's body to a self-executing function. From the fine manual (bottom of the section):
When using a JavaScript loop to generate functions, it's common to insert a closure wrapper in order to ensure that loop variables are closed over, and all the generated functions don't just share the final values. CoffeeScript provides the
do
keyword, which immediately invokes a passed function, forwarding any arguments.
Demo: http://jsfiddle.net/ambiguous/YAqJu/
Upvotes: 4