Immediately invoked function expression without using grouping operator
A function declaration, like
function foo() {
}
defines (and hoists) the variable name foo
as a function in the current scope. A function declaration doesn't evaluate to a value; it just does something, a bit like an if
does something (rather than evaluate to a value).
You can only invoke values which are functions, eg
<somevalue>()
where somevalue
is a variable name that refers to a function.
Note that function declarations require function names, because otherwise there's no variable name to assign the function to - your original
//gives `SyntaxError`
function() {
console.log('Inside the function');
}();
throws not because of the ()
at the end, but because of the lack of a name.
You can put parentheses at the end of a function declaration, as long as there's something inside the parentheses - but these parentheses do not call the function, they evaluate to a value:
function x() {
console.log('Inside the function');
}(console.log('some expression inside parentheses'));
The interpreter sees these as two separate statements, like
function x() {
console.log('Inside the function');
}
// completely separate:
(console.log('some expression inside parentheses'));
The inside of the parentheses gets evaluated and then discarded, since it doesn't get assigned to anything.
(Empty parentheses are forbidden because they can't be evaluated to a value, similar to how const foo = ()
is forbidden)
In your code you don't have name for the function that's the reason for syntax error. Even if you would had name it would have thrown error.
function func(){
console.log('x')
}();
The reason is the function declaration doesn't return the values of the function however when you wrap function declaration inside ()
it forces it be a function expression which returns a value.
In the second example the function() {console.log('Inside the function')}
is considered expression because it's on RightHandSide. So it executes without an error.
Is there a way we can immediately invoke a function declaration without using IIFE pattern
You can use +
which will make function declaration an expression.
+function(){
console.log('done')
}()
If you don't want to use +
and ()
you can use new
keyword
new function(){
console.log('done')
}
Extra
A very interesting question is asked by @cat in the comments. I try to answer it.There are three cases
+function(){} //returns NaN
(+function(){return 5})() //VM140:1 Uncaught TypeError: (+(intermediate value)) is not a function
+function(){return 5}() //5
+function(){}
returns NaN
+
acts as Unary Plus here which parses the value next to it to number. As Number(function(){})
returns NaN
so it also returns NaN
(+function(){return 5;})()
returns Error
Usually IIFE are created using ()
. ()
are used to make a function declaration an expression +
is short way for that. Now +function(){}
is already an expression which returns NaN
. So calling NaN
will return error. The code is same as
Number(function(){})()
+function(){return 5;}()
returns 5
In the above line +
is used to make a statement an expression. In the above example first function is called then +
is used on it to convert it to number. So the above line is same as
Number(function(){return 5}())
In the proof of statement "+ runs on after the function is called" Consider the below snippet
console.log(typeof +function(){return '5'}());
So in the above snippet you can see the returned value is string '5'
but is converted to number because of +