0

I have two questions about this counter example.

  1. Why doesn't addVersionOne work? Why is it returning the actual code instead of a number?
  2. How does addVersionTwo work? Isn't counter being reset back to 0 every time the function is run?

const addVersionOne = function() {
  let counter = 0;
  return function() {
    counter += 1;
    return counter;
  }
}

var addVersionTwo = (function () {
  let counter = 0;
  return function() {
    counter += 1; 
    return counter;
  }
})();

function writeVersionOne(){
  document.getElementById("addVersionOne").innerHTML = addVersionOne();
}

function writeVersionTwo(){
  document.getElementById("addVersionTwo").innerHTML = addVersionTwo();
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>Page Title</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <button type="button" onclick="writeVersionOne()">addVersionOne</button>
  <button type="button" onclick="writeVersionTwo()">addVersionTwo</button>
  <p id="addVersionOne">0</p>
  <p id="addVersionTwo">0</p>
  <script src="main.js"></script>
</head>
<body>
  
</body>
</html>
InspectorDanno
  • 935
  • 2
  • 12
  • 23
  • because the second one executes the outer function while the first one is the outer function.... – epascarello Nov 27 '18 at 17:53
  • Second is an IIFE-> "Immediately invoking function expression". Search that term and do some reading – charlietfl Nov 27 '18 at 17:54
  • when you use `let` then it will not redeclare the variable please check this answer for clarification https://stackoverflow.com/a/11444416/4492504 – Zain Aftab Nov 27 '18 at 17:56
  • 1
    @ZainAftab: That's not correct in this context. There is no difference between using `let` and `var` here. – Felix Kling Nov 27 '18 at 18:00

2 Answers2

1

When you execute this:

addVersionOne()

What is the result? Well, let's see what that function returns:

//...
return function() {
    counter += 1;
    return counter;
}

It returns a function. That function is never executed, it's just returned. The function itself is being set as the innerHTML for your target element.

But what does this return?:

addVersionTwo()

Notice how your second version wraps everything in parentheses and then adds another set of parentheses to invoke the returned function. So while the variable addVersionOne is a function which returns a function, the variable addVersionTwo is that returned function. And it returns a value:

//...
return counter;

Isn't counter being reset back to 0 every time the function is run?

Which "function" are you referring to? You have several. This function is being executed once when the page loads:

function () {
    let counter = 0;
    return function() {
        counter += 1; 
        return counter;
    }
}

It then returns a function which is stored in the addVersionTwo variable. That function is:

function() {
    counter += 1; 
    return counter;
}

And no, that function does not reset counter to 0 each time it is executed.

David
  • 208,112
  • 36
  • 198
  • 279
0

Because the return value of the function addVersionOne is a function and it is obvious. But addVersionTwo function is actually the result of a function call which returns a function. So, addVersionTwo is actually the function below:

return function() {
    counter += 1; 
    return counter;
}

you could define the function addVersionTwo as follows:

var counter = 0;

var addVersionTwo = function() {
    counter += 1; 
    return counter;
};