Immediately Invoked Function Expressions (IIFE)
Open the project folder
In our starter files, open the index.html page from this lessons folder:
03.Functions > 03.Immeditely-invoked-function-expressions
Converting a function to an IIFE
Now we know what function expressions are, next we will look at immediately invoked function expressions. It sounds complex, but it’s not really. Just take our function expression from previously, and we can run or “invoke” it immediately.
Looking at the starter file here:
function hey() {
alert('HEY');
}
hey();
As we know, this is a function declaration. But we can remove the function name, this is optional and again we will look at this very soon:
function() {
alert('HEY');
}
hey();
And since it has no name, we can remove the function call hey()
. This lack of name means it is an anonymous function. So how do we call a function with no name?
Well, this is where the immediately invoked function expression comes into play. First, we wrap the full function in brackets to group it together:
(function() {
alert('HEY');
})
And then to call it, we add the brackets just after, like with a regular function call:
(function() {
alert('HEY');
})()
What we have done here is create a function and run it immediately. If we did not surround our function with the brackets, it would cause an error since JavaScript would think this was a regular function which required a name.
Using with semi-colons
But these surrounding brackets can also cause a problem. If we have some code above such as a variable, with no semi-colon at end:
var language = 'JavaScript' // no semi colon
(function () {
alert(language);
})();
Notice here we are not using a semi colon at the end, saving this file in a text editor may cause the code to re-format like this (don’t worry if not):
var language = 'JavaScript'(function () {
alert(language);
})();
This will then cause an error in the console:
Uncaught TypeError: "JavaScript" is not a function
We see this error because it thinks the string of JavaScript is a function. If we examine our code, this is more understandable:
'JavaScript'()
This is similar to how we create a function.
Remember earlier we looked at semi-colons and how we don’t have to always use them. This is one of the cases when we should use them, and a semi-colon after our variable line will fix the issue Alternatively, you may also see the function with a semi-colon at the beginning like this:
;(function () {
alert(language);
})();
And this is a way to avoid any errors if the above line is not ended in a semi colon. Especially if we are importing the contents of another file and the issue is not immediately obvious.
Why use an IIFE?
This is how we use them, but why do we use them?
Apart from the obvious that we may need to run some code immediately without calling a function, since this is a function expression, it does not pollute the global object.
Also, we can keep other variables off the global object too if we only intend to use them inside the function. For example, we already alert
our variable inside the function like this:
var language = 'JavaScript';
(function () {
alert(language);
})();
And then also log the language to the console below this:
console.log(language);
The alert and console log will show that the language
variable is available from both outside and inside the function. But, moving the variable down into the function will isolate this variable to the function only:
(function () {
var language = 'JavaScript'; // var now inside of function
alert(language);
})();
console.log(language);
We will see the alert, but the console log has an error:
Uncaught ReferenceError: language is not defined
Meaning that variables created inside of this function are isolated. If we needed to return a value from the function, we can store it in a variable:
const lang = (function () {
var language = 'javascript';
return language;
})();
console.log(lang);
And this is a way to access the enclosed variable from outside the function.