- https://stackoverflow.com/questions/1634268/explain-the-encapsulated-anonymous-function-syntax
- https://stackoverflow.com/questions/440739/what-do-parentheses-surrounding-an-object-function-class-declaration-mean
The Problem
In javascript, we implement twoPlusTwo.
1 2 3 4 5 |
function twoPlusTwo(){ console.log(2 + 2); } twoPlusTwo(); // 4 |
You can also create an anonymous function and assign it to a variable:
1 2 3 4 |
var twoPlusTwo = function(){ console.log(2 + 2); }; twoPlusTwo(); // 4 |
You can encapsulate a block of code by creating an anonymous function, then wrapping it in brackets and executing it immediately:
1 2 3 |
(function(){ console.log(2 + 2); // 4 })(); |
However, this does not work:
1 2 3 |
function(){ console.log(2 + 2); }(); |
Why?
Answer
1 2 3 |
function(){ console.log(2 + 2); }(); |
doesn’t work because:
1 2 3 |
function(){ console.log(2 + 2); } |
is being parsed as a Function Declaration, and the name identifier of function declarations is mandatory.
Also,
1 2 3 |
function(){ console.log(2 + 2); }(); |
is same as
1 2 3 4 5 |
function(){ console.log(2 + 2); } (); |
The reason this wouldn’t work is that the JavaScript engine interprets this as a function declaration followed by a completely unrelated grouping operator that contains no expression, and grouping operators must contain an expression.
Surrounding it with a parentheses
Now, when you surround it with parentheses like so:
1 2 3 |
(function(){ console.log(2 + 2); // 4 })(); |
it is evaluated as a Function Expression, and function expressions can be named or not.
i.e:
1 2 3 4 5 6 7 |
var a = function() { // un-named function expression } var getType = function funName(variable) { // named function expression } |
…and thus, wrapping parenthesis around it, it gets the result of that expressions in the same way having a variable assigned to the result:
1 2 3 4 5 6 7 |
// function expressions f is returned to variable f var f = function f() { } // anonymous 'function expression' is returned (function() { }) |
The only difference is that we assigned function f to a variable. But we didn’t assign the anonymous function anywhere.
Let’s try assigning it to a variable so we can see the similarities:
1 2 3 4 5 6 7 8 9 10 11 12 |
var f = function f() { console.log("f"); } f(); // f // anonymous 'function expression' is returned var a = (function() { console.log("anon func") }) a(); // anon func |
or simply
1 2 3 |
(function() { console.log("anon func") })(); // anon func |
as an Immediately Invoked Function Expression
The Function Expression used in this term is directly to indicate anonymous function expression.
The Immediately Invoked used in this term is the ( … ) that gets the function expression, which is pushed onto the local stack. We don’t see it because we did not assign any named reference variables to it. Just know that it is pushed onto the local stack.
Then this function expression is executed via ().
Further Information
The ‘()’ surrounding the anonymous function is the ‘grouping operator’ as defined in section 11.1.6 of the ECMA spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf.
Taken verbatim from the docs:
11.1.6 The Grouping Operator
The production PrimaryExpression : ( Expression ) is evaluated as follows:
Return the result of evaluating Expression. This may be of type Reference.
In this context the function is treated as an expression.