I'm currently finishing reading up on JavaScript. I am on the chapter about closures in JavaScript (to allow "private variables"), on .asp.
The example is a counter:
<!DOCTYPE html>
<html>
<body>
<p>Counting with a local variable.</p>
<button type="button" onclick="myFunction()">Count!</button>
<p id="demo">0</p>
<script>
var add = (function () {
var counter = 0;
return function () {return counter += 1}
})()
function myFunction(){
document.getElementById("demo").innerHTML = add();
}
</script>
</body>
</html>
It states that it makes use of a self-invoking function to set the counter to 0 once, and increments counter by one for every iteration of add(). However, I see in the code that the curly braces used to self-invoke a function is around both the counter = 0
and the function to increment counter. It's just difficult for me to visualize how exactly both mands can be inside the self-invoking function but one runs only once, while the other runs every iteration.
I'm currently finishing reading up on JavaScript. I am on the chapter about closures in JavaScript (to allow "private variables"), on http://www.w3schools./js/js_function_closures.asp.
The example is a counter:
<!DOCTYPE html>
<html>
<body>
<p>Counting with a local variable.</p>
<button type="button" onclick="myFunction()">Count!</button>
<p id="demo">0</p>
<script>
var add = (function () {
var counter = 0;
return function () {return counter += 1}
})()
function myFunction(){
document.getElementById("demo").innerHTML = add();
}
</script>
</body>
</html>
It states that it makes use of a self-invoking function to set the counter to 0 once, and increments counter by one for every iteration of add(). However, I see in the code that the curly braces used to self-invoke a function is around both the counter = 0
and the function to increment counter. It's just difficult for me to visualize how exactly both mands can be inside the self-invoking function but one runs only once, while the other runs every iteration.
-
2
The declaration of the IIFE (Immediately Invoked Function Expression) returns another function. So the initial run of the IIFE creates the
counter
variable and returns a function that does work on thecounter
variable. So when you calladd()
you are not running thevar counter = 0
code, you're running thereturn
of the IIFE (which happens to be a function). – Jasper Commented Jun 17, 2014 at 20:54 -
counter += 1
can be++counter
. – RobG Commented Jun 17, 2014 at 21:05
1 Answer
Reset to default 10Let's break this problem down into pieces :
(1)
var add = (function () {
var counter = 0;
return function () {return counter += 1;}
})();
first part is the self invoking anonymous function, this means that add
will receive the result of execution of this function. Which in this case is nothing but the following anonymous function :
function () {return counter += 1;} (2)
so this means that add will be a function !
Now the fun part is that inside the siaf (1) (self-invoking-anonymous function), we're declaring a counter variable, initialized to zero :
var counter = 0;
since counter belongs to the outer scope of (2), then (2) has access to it!
what JavaScript says, is that a function when created will capture its environment and persist it, so a closure (close over) is nothing but the bination of a function and its creation environment. That means that after return statement the add function which will now hold a reference to (2) will still have access to the counter variable which is initially set to 0;
so to increment the counter, we need increment (2), which means incrementing add like so :
add();
p.s : function created with Function constructor and returned in the same way as (2) won't capture the counter variable !!