Search code examples
javascriptclosurescounteriife

JavaScript counter with closure and IIFE


On www.w3schools.com/js/js_function_closures.asp there is a basic example of a counter in a closure, and as far as I can tell, an IIFE:

var add = (function () {
    var counter = 0;
    console.log(counter);
    return function () {return counter += 1;}
})();

add();
add();
add();

// the counter is now 3 

However, after hours of reading on scope, closures and IIFEs, not for the first time, and looking at other simple examples, I still don't understand why the var counter = 0; line is only executed once. The console log I added right after that line never outputs anything, as if it never gets called.

Why is the counter not reset at 0 every time add() is called? What concept(s) am I understanding wrong? Thank you for your help.


Solution

  • The first step for the Javascript engine (after declaring add) is to initialize add which results in an invocation of the IIFE which again results in:

    var add = function () {
    
        return counter = counter++
    }
    

    because the IIFE returns this function as the value to be assigned to add. The function assigned to add still has access to the lexical scope of the IIFE (var counter): that is closure.

    Each add() is an invocation of the function returned from the IIFE and therefore var counter = 0 is only invocated once (at the time of initializing add).