What is the lifetime of variables inside a self calling function in javascript
The same as variables in any other kind of JavaScript function: They exist for as long as they can be referenced, which sometimes means long past the time the function that contains them returns.
Your counter
variable continues to exist after the IIFE returns because the function it creates and returns (return function () {return counter += 1;}
) is a closure over the variable. The variable will exist as long as that function exists.
More technically: Calling a function creates something called an execution context for that call, which has a variable enviroment object. Any function created during the call receives a reference to that outer variable environment object; that object, like all objects, exists as long as there's a reference to it, and so the functions keep the object alive. Variables are actually properties of that variable environment object, and so they exist as long as something references the object they're on. (This is the very simplified form.) While in theory the entire variable environment object is kept, in practice JavaScript engines are free to optimize if the effects of optimization aren't observable, so a variable that isn't actually used by the closure may (or may not) be released, depending on the engine and the code in the function.
Your IIFE can only be called once, so there can only be one counter
, but it's common for a function creating a closure to be called more than once, in which case you have multiple variable objects, and multiple copies of the variables that are closed over.
Example:
function helloBuilder(name) {
var counter = 0;
return function() {
++counter;
display("Hi there, " + name + ", this is greeting #" + counter);
};
}
var helloFred = helloBuilder("Fred");
var helloMaria = helloBuilder("Maria");
helloFred(); // "Hi there, Fred, this is greeting #1"
helloFred(); // "Hi there, Fred, this is greeting #2"
helloMaria(); // "Hi there, Maria, this is greeting #1"
helloMaria(); // "Hi there, Maria, this is greeting #2"
helloFred(); // "Hi there, Fred, this is greeting #3"
function display(msg) {
var p = document.createElement('p');
p.appendChild(document.createTextNode(msg));
document.body.appendChild(p);
}
In the above, the function returned by helloBuilder
closes over both its name
argument and its counter
variable. (Because arguments are also stored on the execution context's variable object.) So we can see that after calling it twice, there are two variable objects, each with its own name
and counter
, one referenced by each function we asked helloBuilder
to create.