This is the snippet of code that led to me finally understanding closure. This also the snippet of code that I bombed during a technical interview when the person interviewing me asked what this logged to the console, and I replied, "0, 0, 0." The correct answer was, "1, 2, 3."
How is this possible you ask? With closure!
This is very simplistic example of a closure, but it is still a closure nonetheless. Anytime you access a variable from outside the inner scope, you are dealing with a closure.
Now if we return to the earlier code snippet, we can see a more complex example of closure in action.
When you create a new variable and set it equal to a function definition, that variable contains not only the function definition, but also a closure. The closure includes the variables that were in scope when the function was defined. In this case, we set the variable increment equal to the return value of the the function createCounter(), and the return value of createCounter() is myFunction which is a variable set equal to a function that increments and returns the counter variable which is declared in the scope directly above it.
Since increment is now a variable essentially set to the uninvoked function myFunction, whenever we call increment() it is basically the same thing as if we were calling myFunction(). And if we look at the code we know that myFunction is set equal to a function that increments and returns the counter variable which it has access to in the scope directly above it.