Explain why the following doesn't work as an IIFE: "function foo(){ }();". What needs to be changed to properly make it an IIFE?
Abdullah Al Numan
Posted on July 21, 2022
This code returns a token error:
function foo(){ }(); // Error: Unexpected token ')'
Parens
If we place an expression inside the second parens (the grouping operator, which expects an expression to be evaluated), the error goes away.
function foo(){ }(1);
So, we know the token error is due to the second parens, which did not have any expression to evaluate.
But... it still doesn't work as an IIFE.
Breakdown
Let's change foo()
to log a greeting. As you can see, nothing gets logged to the console.
function foo(){ console.log('Hello from foo!') }(1); // Nothing logged to the console
This is because foo()
is never invoked.
In fact, we are wrong in expecting foo()
to be invoked like this:
function foo(){ console.log('Hello from foo!') }();
Because, the second parens does not stand for invoking foo()
here. And that is because the function declaration left to it, function foo(){ }
, is not an expression. It's just a definition.
The parser sees the code above as:
function foo(){ console.log('Hello from foo!') };
();
Fix
In order to make the second parens (immediately) invoke foo()
, we need to make the function declaration evaluate to a function expression first. And guess what, we do it with another parens.
(function foo(){ console.log('Hello from foo!') });
We can then go ahead and apply the invocation parens:
(function foo(){ console.log('Hello from foo!') }(); // "Hello from foo!"
Another fix would be to wrap the entire code in an overarching parens. This will also make it work as an IIFE:
(function foo(){ console.log('Hello from foo!') }()); // "Hello from foo!"
Here, everything, including the last parens is considered part of one expression and so foo()
gets invoked.
References
Posted on July 21, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
May 1, 2023