Immediately invoked function expressions, or IIFE, are functions which are run as soon as you define the function. You may also see people refer to them as anonymous functions. They give us an easy way to isolate variables within a function, and not globally - after which we can easily run the function immediately. They are also useful for running async functions, when a top level await
is not available.
While we usually define functions like this:
let x = () => {
console.log("hello");
}
let y = function() {
console.log("world");
}
function z() {
console.log("!");
}
x(); y(); z();
Defining an IIFE means invoking the function as we write it. So we can define an IIFE like this:
(function() {
console.log("hello world!")
})()
This function is anonymous (it has no name) - and it runs immediately. You can also run it using arrow notation, like this:
(() => {
console.log("hello world!")
})()
While the IIFEs above to do not have names, you can give them names. It doesn't really make sense, though, since you can't call them anywhere else. Once the function is created and called in this format, it cannot be used anywhere else. That means that in the example below, trying to call myFunction()
somewhere else will not work:
(function myFunction() {
console.log("hello world!")
})()
Anonymous or Immediately invoked function expressions can be used to encapsulate async behaviour. You can still make an IIFE asynchronous by using the async
keyword:
(async () => {
console.log("hello world!")
})()
Giving arguments to IIFEs in Javascript
We can pass variables straight into an IIFE using the expected format. For example, below we have an argument in our IIFE - which is x
. We can pass in a value for x
by using the last set of parenthesise:
let getNumber = 10;
(function(x) {
console.log(x + 10)
})(getNumber) // console logs 20
The defensive semi colon in IIFEs
You may sometimes see the following code when IIFEs are defined where a semi colon is added to the start.
;(() => {
return 10;
})
This seems confusing but it's to avoid a weird issue where, if the previous line doesn't have a semi colon, the function last line will be used as the function name. Consider this code:
let b = 5
let c = 10
let a = b + c
(function () {
return 10
})();
If someone forgot to put a semi colon on let a = b + c
, or if you imported the IIFE onto a line where the previous one did not contain a semi colon, you may run into some weird bugs. In the above example, you'll get the error Uncaught TypeError: c is not a function
. This is because the code interprets this as trying to run the c
function. In essence, the code sees this:
c(() => {
return 10
})()
So defensive semi colons at the start of IIFEs is an easy way to avoid this scenario.
Conclusion
IIFEs are commonly found in Javascript code bases and have been a useful way to perform a number of things like asynchronous code and scoping variables or code within a specific function block. While there are now other ways to achieve this in Javascript, you're still going to see these all over the place - so understanding how they work is important.
Top comments (0)