IIFE
Immediately Invoked Function Expression
An IIFE is function that executes immediately after it is defined (usually anonymously defined and not called again).
The advantage is that it keeps all its objects limited to its scope, which avoids polluting or overwriting variables or functions in the global namespace. This is useful in the browser, to avoid conflicting with other modules.
Resources
Syntax
Brackets
Enclose a function inside a pair of brackets and then invoke it.
(function () {
statements
})();
Character
If you prefer, you can use the not operator instead of the pair of brackets.
!function () {
statements
}();
Examples
The function becomes a function expression which is immediately executed. The variable within the expression can not be accessed from outside it.
(function () {
var aName = "Barry";
})();
// Variable aName is not accessible from the outside scope
aName // throws "Uncaught ReferenceError: aName is not defined"
Assigning the IIFE to a variable stores the function’s return value, not the function definition itself.
const result = (function () {
var name = "Barry";
return name;
})();
// Immediately creates the output:
result; // "Barry">
Comparison
Standard
- Plain function
function () { console.log("Hello") }
- Adding a call at the end will give a syntax error.
function () { console.log("Hello") }()
IIFE
Surround the function in brackets before calling it will work.
(function () {
console.log("Hello")
})()
Make sure the previous line ends with a semicolon, otherwise you’ll get an error.
e.g.
x = y;
(function () {
statements
})();
// i.e.
x = y(function () { statements })();
Instead of brackets, you can use the not operator at the start. This will treat the function as an expression and return true
(since the opposite of !undefined
is true
).
!function () {
console.log("Hello")
}()
This is lighter to read than the brackets pair. The intent is also clearer (brackets are all over a script but exclamation point is rare. Further, this avoids the issue of making sure the previous line has a semicolon.
This is valid:
x = y
!function () {
statements
}()
Scope
An IIFE is useful to put functions and variables in the scope of a module, so they don’t fill the global scope in the browser.
If you need access to the window or document, pass those in explicitly.
And you probably want to persist functions or variables outside the IIFE, so attach them to the window object.
!function (window) {
statements
}(window);
Using document:
!function (window, document) {
statements
}(window, document);
e.g.
main.js
!function (window) { const MY_GLOBAL_VAR = 123 const MY_SCOPED_VAR = 456 function myFunc() { // ... } window.myFunc = myFunc window.MY_GLOBAL_VAR = MY_GLOBAL_VAR }(window);
index.html
<script> window.myFunc(1, 2, 3); console.log(window.MY_GLOBAL_VAR) </script>