IIFE (Immediately Invoked Function Expression) is a JavaScript function that runs as soon as it is defined.
Let's see an example:
(function demo() {
console.log('This is a IIFE');
})();
If you run the codes above you will see the output immediately. This is a typical IIFE. But it could be completely replaced by single line code console.log('This is a IIFE');
. Then why do we need IIFE?
IIFE helps to write elegant codes
Sometimes we have to define a function. For example await
has to be used in an async function and recursion is generally connected with a function.
If the function is called only once IIFE will help to write elegant codes.
Let's see some example:
async function
Without IIFE we need to define an async function and call it:
function resolveAfterSeconds(x) {
return new Promise(resolve => {
setTimeout(() => {
console.log('Hello');
resolve();
}, x);
});
}
async function demo() {
await resolveAfterSeconds(2000);
console.log('IIFE');
}
demo();
With IIFE you can simply run the async function directly:
function resolveAfterSeconds(x) {
return new Promise(resolve => {
setTimeout(() => {
console.log('Hello');
resolve();
}, x);
});
}
(async function demo() {
await resolveAfterSeconds(2000);
console.log('IIFE');
})();
You even don't need to give a name to the async function:
function resolveAfterSeconds(x) {
return new Promise(resolve => {
setTimeout(() => {
console.log('Hello');
resolve();
}, x);
});
}
(async () => {
await resolveAfterSeconds(2000);
console.log('IIFE');
})();
recursive function
Recursive function is the same as async function. Let's take factorial for example.
Without IIFE:
function factorial(number) {
if (number <=0) {
return 1;
} else {
return number * factorial(number - 1);
}
}
factorial(8);
With IIFE:
(function factorial(number) {
if (number <=0) {
return 1;
} else {
return number * factorial(number - 1);
}
}(8));
IIFE allows to create a new block scope
What does it mean by create a new block scope? If you try to run the codes below:
for (var i = 0; i < 5; i++) {
setTimeout(function () {
console.log('index: ' + i);
}, 1000);
}
You will be surprised at the result:
index: 5
index: 5
index: 5
index: 5
index: 5
But if you run with IIFE:
for (var i = 0; i < 5; i++) {
(function logIndex(index) {
setTimeout(function () {
console.log('index: ' + index);
}, 1000);
})(i)
}
You will get exactly what you want:
index: 0
index: 1
index: 2
index: 3
index: 4
You will learn more about the example above from IIFE section in Understanding Scope in JavaScript.