IIFEs in Coffeescript

In JavaScript we often use Immediately Invoked Function Expessions Show archive.org snapshot (or IIFEs) to prevent local variables from bleeding into an outside scope:

(function() {
  var foo = "value"; // foo is scoped to this IIFE
})();

In Coffeescript an IIFE looks like this:

(->
  foo = "value" # foo is scoped to this IIFE
)()

There is also a shorthand syntax with do:

do ->
  foo = "value" # foo is scoped to this IIFE

You can also use do with arguments to capture an outside name into the IIFE's scope:

for filename in list
  # in this line, `filename` is subject to crazy JS/Coffeescript scoping
  do (filename) ->
    # in this line `filename` is scoped to this IIFE

This makes do the best way to emulate let Show archive.org snapshot in Coffeescript.

Example: When you need IIFEs

You would expect the following code to open three dialogs, saying "foo", "bar" and "baz" respectively:

alerters = [];

for i in ['foo', 'bar', 'baz']
  alerters.push 
    -> alert(i)

for alerter in alerters
  alerter()

When running the code however, you will see that the three dialogs say "baz", "baz" and "baz"! This is because they all share the same i variable.

To get the desired bahvior, use do(i) to scope i to each alert function:

alerters = [];

for i in ['foo', 'bar', 'baz']
  alerters.push 
    do (i) -> alert(i)

for alerter in alerters
  alerter()
Henning Koch About 8 years ago