Reputation: 918
As my understanding, closure makes an environment to link functions and parameters outside the function and allow things inside the function to access them.
As below is a function with closure. When I execute this function three times.
add();
add();
add();
I expect I should get 1, because everytime I execute add(), It will redeclare counter as 0 and add 1. So it should be counter = 0, counter++, counter = 0, counter++, counter = 0, counter++. But why it turned out to be 3?
var add = (function () {
var counter = 0;
return function () {return counter += 1;}
})();
function myFunction(){
document.getElementById("demo").innerHTML = add();
}
Second question is :
variable = (function() {})()
Why we add an extra parenthesis to enclose the function, and why another extra parenthesis after the function?
Thanks!
Upvotes: 0
Views: 38
Reputation: 816442
I expect I should get 1, because everytime I execute add(), It will redeclare counter as 0 and add 1.
No, exactly not. add
refers to the function you are returning from the IIFE, i.e. to function () {return counter += 1;}
. This function doesn't set counter
to 0.
Lets just log add
and have a look at it:
Do you see now that calling add
will simply add 1
to counter
, and nothing else?
Maybe the code is easier to understand if you extract the function. The following code has exactly the same result as yours:
function createAdd() {
var counter = 0;
return function () {return counter += 1;}
}
// we are *calling* createAdd here, so `add` refers
// to the function defined in line 3 ( function () {return counter += 1;} )
var add = createAdd();
add();
add();
add();
Here you can see that createAdd
(and therefore the line var counter = 0
) is executed only once, but the function returned from createAdd
is executed multiple times.
Why we add an extra parenthesis to enclose the function, and why another extra parenthesis after the function?
This is called a immediately invoked function expression (IIFE). It defines a function and immediately executes it. This is often done to limit the scope of variables (in this case counter
).
You can think of (function() {}())
being equivalent to
function f() {}
(f())
The IIFE just puts the declaration and execution of the function into a single expression. This allows us to omit the function name so that we don't pollute the scope.
Related question:
Why declaration of variable in closure environment did not work?
I'd say it works correctly as intended.
Upvotes: 3