Questions tagged [iife]

In Javascript, an IIFE stands for an Immediately-Invoked Function Expression: a function expression that gets invoked immediately after it is defined, such as (function(){ /* code */ })();

IIFE stands for Immediately-Invoked Function Expression. It is used mainly to describe the pattern in JavaScript where a function expression is executed immediately after it is defined. IIFEs usually have the following syntax in JavaScript:

(function() { /* code */ })();

But there are several other valid ways to form an IIFE mentioned in this answer, such as

(function() { /* code */ }());
new function(){ /* code */ }();

The term IIFE was first proposed by Ben Alman in this article, in which he suggests the pronunciation "iffy". He proposed this term as an alternative to what he calls the "popular but misleading term self-executing anonymous function".

The most common notations used today are (function(){}());, with the invoking parentheses inside the grouping (), and (function(){})();, with the invoking parentheses outside of the group.

Apart from there being a minor semantic difference between the two (the first evaluates to (returnvalue of IIFE), whereas the second evaluates to (defined function)<=(call)) they are both equally valid, though the renowned JavaScript expert Douglas Crockford considers the second notation as being "wrong" and "illogical":

When a function is to be invoked immediately, the entire invocation expression should be wrapped in parens so that it is clear that the value being produced is the result of the function and not the function itself.

From Code Conventions for the JavaScript programming Language.

The term IIFE was rapidly adopted by the community after it was first coined at the end of 2010. Simply because it's the most accurate description of the pattern itself:

  • II (Immediately-Invoked): The function is defined, and invoked in one go. That's pretty clear
  • F (Function) It's a function...
  • E (expression): Not just any old function: it's an expression rather than a statement. This is crucial.

The difference between a function definition and a function expression is where the function is defined (sticking to JavaScript for examples).

// Any old function:
function f(arg)
{
    return arg;
}

This function definition will be hoisted to the top of its scope, and be made accessible all over that scope:

console.log(f(123));
function f(n)
{
    return (typeof n);
}

will neatly log number, even though the function seems to be called prior to it being defined.

By turning the function into an expression, the definition cannot be hoisted:

console.log(typeof f);
var f = function()
{
    return 'something';
};
console.log(typeof f);

In this example, the only thing that will be hoisted is the declaration of the variable f. The function definition itself is an expression, in the shape of the right hand operand of an assignment. Assignments are never hoisted, so the code will log undefined, and then function.

To turn this Function Expression into an IIFE, we have to do two things: Make sure the function definition is an expression, rather than a statement. As explained above, this is achieved by wrapping the function in the grouping () operator, or adding a logical- or bitwise operator to the statement, the void prefix or the new keyword.

Notes:

Using the void prefix effectively suppresses the return value of the IIFE, and always returns undefined:

var foo = void function()
{
    console.log('called');
    return 'returnVal';
};
console.log(foo);

Logs called, and then the value of foo -> undefined.

Using the new keyword will affect the call-context (this reference) of the IIFE_: The IIFE will behave as a constructor, returning a new object:

new function()
{
    return this.constructor;
};

will return a reference to the function that was just called.

Specific use cases:

  • IFFE's are often used when passing a function as an argument to another function (most notably to solve the infamous loop problem)
  • Custom constructors often are wrapped in an IIFE, to allow for pseudo (private-) static properties. Variables declared in the IIFE's scope stay in memory for as long as the return value of that IIFE is referenced somewhere. This return value can be an object, with a function that in turn references variables from the IIFE's scope. Here's an example.
  • In some browsers, older versions of Internet Explorer in particular, attaching event handlers directly to DOM references caused memory leaks, owing to Internet Explorer managing the memory for the DOM and its JScript engine separately. The only way around this is to attach listeners in an IIFE. When the script terminates, the GC (Garbage Collector) can flag & swipe the entire IIFE's scope and, with it, all DOM references and event handlers are deallocated.
  • Certain patterns, like the module pattern, requires an IIFE. In this function, the module is built up, and eventually exposed (by assigning a global variable) or returned.
  • Sometimes, the entire script is wrapped in an IIFE, to avoid global variables. This is, however, considered a quick-'n-dirty fix.
645 questions
34
votes
2 answers

Why use NOT operator on anonymous function call? (a la Knockout 2.1.0)

Possible Duplicate: What does the exclamation mark do before the function? If you look at the source code for KnockoutJS 2.1.0 you will see a code structure like this start on line 7: !function(factory) { ... }(factoryDefinition); The not…
CgodLEY
  • 994
  • 8
  • 16
31
votes
4 answers

JQuery best practice, using $(document).ready inside an IIFE?

I am looking at a piece of code: (function($) { // other code here $(document).ready(function() { // other code here }); })(jQuery); I though the IIFE does the functions of $(document).ready, is this code correct? or…
webmedia
  • 341
  • 1
  • 3
  • 8
30
votes
4 answers

!function(){ }() vs (function(){ })()

While reviewing some of the code written in the Twitter Bootstrap Javascript, it looks like they're calling immediately invoked anonymous functions like this: !function( $ ) { ... }(window.jQuery || window.ender); Where I've traditionally…
jondavidjohn
  • 61,812
  • 21
  • 118
  • 158
25
votes
6 answers

Immediately invoked function expression without using grouping operator

I'm trying to immediately invoke a function without using IIFE pattern (enclosing a function definition inside parentheses). Here I see two scenarios: When a function declaration is invoked immediately: gives SyntaxError. When a function expression…
Aaditya Sharma
  • 3,330
  • 3
  • 24
  • 36
24
votes
6 answers

Javascript self executing function "is not a function"

I have: var Init = (function() { my js goes here })(); And my js executes correctly when the page is loaded. I also have: $('form :checkbox').change(function() { Init(); }); But firebug says Init is not a function.
Phillip Senn
  • 46,771
  • 90
  • 257
  • 373
23
votes
5 answers

Enums in TypeScript: what is the JavaScript code doing?

The following TypeScript: enum PrimaryColors { Red, Green, Blue }; Produces the following JavaScript: var PrimaryColors; (function (PrimaryColors) { PrimaryColors[PrimaryColors["Red"] = 0] = "Red"; PrimaryColors[PrimaryColors["Green"] = 1]…
Late Starter
  • 1,069
  • 2
  • 13
  • 24
22
votes
2 answers

Do we need to wrap ES6 code in an IIFE?

In ES5, writing such code has been considered as good practice: (function () { //some magic })(); But in ES6 variables created with let keyword are not attached to window object. So, is there any need now in writing our code in an IIFE, or it…
22
votes
3 answers

Is there any reason to define module.exports using an IIFE?

My team doesn't have any experienced JS developers, but we are writing a library in Node and got a suggestion from a real JS developer that "We should make the js more modular - not to pollute the global namespace and to make it more readable to…
Ryan Reich
  • 2,398
  • 2
  • 17
  • 15
20
votes
2 answers

declaring a variable twice in IIFE

I came through this fun quiz on the internet. console.log((function(x, f = (() => x)){ var x; var y = x; x = 2; return [x, y, f()] })(1)) and the choices were: [2,1,1] [2, undefined, 1] [2, 1, 2] [2, undefined, 2] I picked solution 2 TBH,…
Hamza Mohamed
  • 1,373
  • 1
  • 12
  • 28
19
votes
1 answer

Use Gulp to wrap javascript files with a IIFE

I have an angular app that has a lot of .js files. It's boring to add an IIFE to each file and then add 'use strict'. Is there any way to automate this? I use gulp to run tasks.
Papzord
  • 408
  • 4
  • 14
19
votes
1 answer

Create a JS class: IIFE vs return prototype

Let's see two examples in which I'll try to explain what I want to understand. var Car = function(){ // Init class function Car() { }; // Private func/vars var private = { color:'red' }; // Public func/vars Car.prototype = { …
Nestor Britez
  • 1,218
  • 10
  • 14
18
votes
2 answers

Why does TypeScript pack a class in an IIFE?

Here is a TypeScript class: class Greeter { public static what(): string { return "Greater"; } public subject: string; constructor(subject: string) { this.subject = subject; } public greet(): string { …
Miroslav Popov
  • 3,294
  • 4
  • 32
  • 55
16
votes
1 answer

Why is the named IIFE logged instead of the variable with the same name?

I saw the code below that someone posted. I’m confused about what it logs. It logs the function a, not 200. Why? var a = 1; (function a() { a = 200; console.log(a) })()
Marcus Lee
  • 425
  • 2
  • 7
14
votes
2 answers

How do I import an IIFE-based JavaScript module into an Angular TypeScript app?

So I have a third-party SDK written as an oldschool IIFE based module. In other words it looks something like this: var ThirdPartySDK = (function() { var export = {}; // Add some methods to export return export; })(); You would then be…
Zac Delventhal
  • 3,543
  • 3
  • 20
  • 26
14
votes
1 answer

Rollup: globals & external

I'm trying to rollup my completely es6 module repo which has both local imports/export for the projects, and imports to dependencies that are also either scripts or modules. I'm also trying to have a dual build which creates legacy iife modules via…
backspaces
  • 3,802
  • 6
  • 34
  • 58
1
2
3
42 43