This is a great question, and a pretty advanced topic. You got this!
So, when we see this:
This is a function that immediately runs. The function body, wrapped in the first
() is the functions definition, and the last
() tells our function to immediately execute. This is often referred to as an IIFE, an immediately invoked function execution. It just means we define and run the function all at once.
And when we do that, our function starts running. First thing it does, it creates a “scope,” a private space for its variables to live. Those variables are only available to things that are defined within that scope, and those variables are thrown out as soon as everything that refers to them stop. So normally, the function ends and its internal data is erased.
Unless… What if we couple somehow return something from our function, *that could keep a line into that function? It’s still observing those values, so they never get erased! And they’re still private, only available to things created within that function!
That is what happens here. The outer function creates a variable, and then returns a function that can continue to interact with and tell us about that variable. This is called a closure: a closed scope, with some way to access it.
Each time you run
add(), you are running the inner function, which can increment and share that value of
counter inside that scope. nothing else can see or touch that
counter inside the outer function, it is truly private.
For more, i might Google MDN closures.