1

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.com/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 commands can be inside the self-invoking function but one runs only once, while the other runs every iteration.

2
  • 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 the counter variable. So when you call add() you are not running the var counter = 0 code, you're running the return of the IIFE (which happens to be a function). Commented Jun 17, 2014 at 20:54
  • counter += 1 can be ++counter. Commented Jun 17, 2014 at 21:05

1 Answer 1

10

Let'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 combination 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 !!

Sign up to request clarification or add additional context in comments.

8 Comments

Forget about "anonymous function", they are both function expressions, or just functions.
they are anonymous functions :)
Is a function expression assigned to a variable any more "anonymous" that a function declaration?
i understand what you mean, by pointing the spec, but trust i prefer calling them anonymous. I could have said function pointer in a C style too :)
developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… The main difference between a function expression and a function statement is the function name, which can be omitted in function expressions to create [[[[anonymous functions]]]].
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.