简体   繁体   中英

Why does one counter work and the other doesn't? (Closures?)

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> 

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.

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;
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM