immediately-invoked-function-expression

Immediately Invoked Function Expression in CoffeeScript

CoffeeScript only has function expression, there are no named functions nor function declaration, as almost everything in CoffeeScript is expression.

Anonymous function can be written as just a dash plus an arrow:

1
->

This will be compiled to JavaScript:

1
(function () {});

This anonymous function can be invoked immediately:

1
2
// (->)()
(function () {})();

The immediately invoked function expression (IIFE) syntax is different from the preferred format in JavaScript. But this is more likely due to the syntax and compilation of CoffeeScript.

Here is one useful example to show the syntax:

1
2
3
4
5
6
// (square = (n) -> return n * n)()
var square;
(square = function(n) {
return n * n;
})();

And a few more without compiled Javascript:

1
2
3
(->)()
(square = (n) -> return n * n)()
console.log (square = (n) -> return n * n)(10) # 100

Immediately Invoked Function Expression

What’s difference between:

1
2
(function(){}());
(function(){})();

This is function declaration:

1
function foo(){}

The identifier of the function declaration is required.

This is function expression:

1
var foo = function(){};

The right hand side of the assignment must be an expression. And function identifier is optional. Check the previous article about the difference between function declaration and function expression.

Now, come in the grouping operator, which return the result of evaluating an expression:

1
(function(){});

If we do it with named function:

1
2
function foo(){}
(foo);

or

1
(function foo(){});

But we haven’t done anything here, in another word, we haven’t invoked the function. We merely evaluate the function in three occasions. Function is object in JavaScript, when you’re evaluating an object, the result is still an object:

1
2
3
4
5
console.log(function foo(){}); // [Function: foo]
console.log(function (){}); // [Function]
function bar(){}
console.log(bar); // [Function: bar]
console.log({}); // {}

Now, let’s apply function invocation, and do it the traditional way:

1
foo();

The function has been invoked, and it will return the result of the function.

Replace the identifier with function declaration:

1
function foo(){}();

However, this does not work. Because interpreter treats it as a function declaration, and ( will become an unexpected token. Function declaration cannot be invoked immediately. So, we need to make it an expression, by using the grouping operator:

1
(function foo(){})();

The function identifier is no longer necessary:

1
(function(){})();

Since grouping operator return the result of the expression, we can just drop it:

1
function(){}();

But this statement becomes a function declaration again, so we need to place the grouping operator around it:

1
(function(){}());

Okay, but what’s difference between:

1
2
(function(){}());
(function(){})();

There is no difference, they are both function expressions being invoked immediately. Function invocation can only be done via function expression. But first one is more align with foo(), the traditional way. According to the Code Convention for JavaScript Programming Language by Douglas Crockford:

When a function is to be invoked immediately, the entire invocation expression should be wrapped in parens so that it is clear that the value being produced is the result of the function and not the function itself.

The invocation expression is function(){}(), and wrap it around parenthesis becomes (function(){}());.

Therefore, this first method is more traditional and preferred.