Arel Lin
Arel Lin

Reputation: 918

Why declaration of variable in closure environment did not work?

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

Answers (1)

Felix Kling
Felix Kling

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:

enter image description here

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

Related Questions