- Global execution context and
- Function execution context
In the article of Yash Agraval we mentioned above, you will find samples of how to resolve an identifier within a lexical environment (and what lexical environment is) and the way JS code execution happens.
The execution of JS code happens in two phases:
- The first phase registers all the variables and function declarations within the current lexical environment.
The current code is scanned for function declarations, function expressions and arrow functions are skipped. For every function that is discovered a new function is created and bound to the environment with the function’s name.
Then the current environment is scanned for variables. Variables defined with var and placed outside other functions are found and an identifier is registered with its value initialized to undefined. If an identifier exists, the value is left untouched.
The hoisting() function is attached to an identifier after setting up the global context. Then in the next step, the variable notyetdeclared is registered and its value is initialized to undefined. The hoisting() function is already registered to an identifier in phase 1 and when the JS code starts executing in the global context in phase 2, it looks up the lexical environment for hoisting and finds the function even before its definition. Notyetdeclared is registered to an identifier and initialized to undefined in phase 1 and hence no error is thrown.
Finally, we are in the hoisting environment.
Also subscribe to our weekly newsletter not to miss anything interesting!