Through this article, we will go through the details of Javascript Immediately Invoked Function Expression (IIFE).
Introduction
An Immediately-invoked Function Expression (known as Self-executing anonymous functions) is a way to execute functions immediately, as soon as they are interpreted at runtime.
IIFE’s are very useful because they can create local scope for the variables without affecting the surrounding code outside of it.
Syntax
IIFE can be defined as the following:
(function() {
// function implementation
})()
It also can be defined as an arrow function:
(() => {
// function implementation
})()
We basically have declared a function expression inside the parentheses, then we’ve appended the ()
to execute the function as soon as it’s get interpreted.
Those wrapping parentheses ()
are actually what make our function, to be considered as an expression.
Regular JS functions strictly require a name, For example:
function doSomething() {}
// Or as an arrow function
doSomething() => {}
While function expressions don’t strictly require a name, we can give it a name as the following:
(function doSomething() {
/* */
})()
Also, as an arrow function
(doSomething = () => {
console.log('Log me please!')
})();

Giving IIFE a name doesn’t change the fact that they get executed as soon as they get interpreted, and they get executed only once, we can’t re-invoke/call IIFE again during run-time.
Scope
IIFE has a function scope, which means it has a private scope for the function implementation, For example:
(function () {
var blogName = 'JS-HowTo';
})();
console.log(blogName); // blogName is not defined here, it's in a different scope.
Simply, you can create variables inside the IIFE, and those variables won’t be available to the outside world.
How IIFE works?
A normal Javascript function looks like the following:
function doSomething() {
console.log('Regular JS function.')
}
// Call the function anytime/anywhere during the run time
doSomething()
We can call doSomething
by choice at anytime/anywhere later during the run-time.
For how IIFE works, simply wrap a function with parentheses, and invoke it by putting ()
after it.
Remember that IIFE gets executed only once and we can’t re-invoke/call it again during the run-time, For example:
(function () {
console.log('Expression JS function.'); // Expression JS function.
})();
Arguments
IIFE accepts any kind of parameters from the outer scope, For example, we need to pass logArgument
value from the outer scope to be used inside the function, we can pass it through the closing parentheses
('Expression JS function.')
(function (logArgument) {
console.log(logArgument); // Expression JS function.
})('Expression JS function.');
What does window
, document
, undefined
mean in IIFE?
If you came across some known Javascript SDKs such as Facebook SDK or Google SDK, you might notice that they are passing window, document, undefined and other parameters to the IIFE, Take the google tag manager script as an example:
https://developers.google.com/tag-manager/quickstart
<!-- Google Tag Manager -->
<noscript><iframe src="//www.googletagmanager.com/ns.html?id=GTM-XXXX"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXX');</script>
<!-- End Google Tag Manager -->
As shown above, they are passing window
, document
and other parameters to the IIFE, the reason behind this:
- Local variables are faster to resolve than global variables.
- Reducing the Javascript bundle size, by minifying/renaming the variables.
(function (w, d) {
// w: refers to window object
// d: refers to document object
})(window, document);
Both of the points above would be noticed and results in better performance on large scale applications.
What about undefined
?
In ECMAScript 3,
is mutable. Which means its value could be reassigned, something like undefined
undefined = true;
But in ECMAScript 5 strict mode ('use strict';
) the parser will throw an error. Before this, the way to protect IIFE’s was by passing undefined
as a parameter, by doing the following:
(function (window, document, undefined) {
})(window, document);
This means if someone came along and did this, it would be okay:
undefined = true;
(function (window, document, undefined) {
// undefined is a local undefined variable
})(window, document);
Alternative syntax using unary operators
IIFE starting with a semicolon (;)
Sometimes you may come across IIFE that starts with a semicolon ;
, which is called the defensive semicolon.
The reason behind this is to eliminate JS files/logic combinations in case it gets blindly combined together, For example, consider we’ve two JS files:
(function(){
console.log('file1')
})()
And
(function(){
console.log('file2')
})()
If you use any kind of code minifying tool, such as Toptal JS minifier to concatenate the code from both files into a single file, it will result in the following:
(void console.log("file1"))(function(){console.log("file2")})()
Which will throw a syntax error when trying t execute it. That’s why it’s preferable to add a leading or defensive semicolon ;
in front of the opening wrapping parenthesis.
Other supported operators can be used within the IIFE
!function () {
}();
+function () {
}();
-function () {
}();
~function () {
}();
That’s It! And as always happy coding!
Photo from Unsplash