Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Immediately Invoked Function Expression: Where to put the parenthesis?

I've seen IIFE's written:

(function() {
    console.log("do cool stuff");
})();

as well as:

(function() {
    console.log("do more cool stuff");
}());

They seem to work the same in any context I've used them, though in cases I've been told one way is right and the other is wrong, vice versa. Does anyone have any solid reason or logic as to it being written one order over the other? Is there some cases where there could be potentially more going on after the function body closes but before the invoking parenthesis come into play, or after but before that final closing parenthesis? I've mostly used these in an Angular module closures and can't seem to find anything on any real reason to go one way or the other, wondering if anyone had different experience.

like image 351
Andrew Clavin Avatar asked Jul 05 '16 03:07

Andrew Clavin


1 Answers

Short answer: It doesn't matter, as long as you put them there.

Long answer: It doesn't matter except in the case of arrow functions, because for JavaScript the only important thing is that they are there. The reason for this is that the language spec defines that a statement must only start with the function keyword if you declare a named function. Hence, it is against the spec to define an IIFE like that:

function () {}();

The workaround for this is to wrap the entire thing in parentheses, so that the statement does not start with the function keyword anymore. You achieve this by using

(function () {})();

as well as by using:

(function () {}());

Which one you choose is completely arbitrary and hence up to you.

I (personally) put the parentheses around the function, not around the call, i.e. like this one:

(function () {})();

Reason: I want to use the smallest portion of code to be wrapped in something that is only needed for technical reasons, and this is the function definition, not the call. Apart from that the spec says that you can not define a function in that way, it is not about calling the function. Hence, I think it's more clear if you wrap the definition, not the call.

edit However, in the case of the arrow function in es6, the invocation must be outside of the wrapper. It being inside the wrapper causes an unexpected token error on the opening parenthesis of the invocation. Not totally clear on the mechanics of why this is so.

like image 86
Golo Roden Avatar answered Sep 24 '22 05:09

Golo Roden