The idea of scoping in JavaScript when originally designed by Brendan Eich came from the HyperCard scripting language HyperTalk.
In this language, the displays were done similar to a stack of index cards. There was a master card referred to as the background. It was transparent and can be seen as the bottom card. Any content on this base card was shared with cards placed on top of it. Each card placed on top had its own content which took precedence over the previous card, but still had access to the prior cards if desired.
This is exactly how the JavaScript scoping system is designed. It just has different names. The cards in JavaScript are known as Execution ContextsECMA. Each one of these contexts contains three main parts. A variable environment, a lexical environment, and a this binding. Going back to the cards reference, the lexical environment contains all of the content from prior cards lower in the stack. The current context is at the top of the stack and any content declared there will be stored in the variable environment. The variable environment will take precedence in the case of naming collisions.
The this binding will point to the containing object. Sometimes scopes or execution contexts change without the containing object changing, such as in a declared function where the containing object may be window
or a constructor function.
These execution contexts are created any time control is transferred. Control is transferred when code begins to execute, and this is primarily done from function execution.
So that is the technical explanation. In practice, it is important to remember that in JavaScript
Applying this to one of the previous examples (5. "Closure") on this page, it is possible to follow the stack of execution contexts. In this example there are three contexts in the stack. They are defined by the outer context, the context in the immediately invoked function called by var six, and the context in the returned function inside of var six's immediately invoked function.
i) The outer context. It has a variable environment of a = 1
ii) The IIFE context, it has a lexical environment of a = 1, but a variable environment of a = 6 which takes precedence in the stack
iii) The returned function context, it has a lexical environment of a = 6 and that is the value referenced in the alert when called.