const firstName = "Jovial";
let lastName = "Kanwadia";

function greet(firstName){
  const fullName = firstName + " " + lastName;
  return "Hello, " + fullName
}

greet();

Creating Phase

Variable hoisting inside Declarative Record

First when variables are declared they use Global Execution Context -> Lexical Environment which points to Global Environment Record -> Declarative Record to handle the identifier bindings created with let and const keywords.

Note: During creation phase of const and let variable and classes they are uninitialized. Meaning that memory space is setup, they are hoisted but they don’t have a value yet, they are only initialized during the execution phase of the execution context. var keyword variables are initialized but set undefined.

Creating of Function Object

Next we have function greet which is handled by the Object Record inside Global Environment Record. Functions are initialized during the creation phase. So a new function object is created for greet.

  1. Environment: It points to the environment record in which it was declared. In this case it is Global Environment Record.
  2. Call Method: It is a method that gets called whenever we invoke the function.

Execution Phase

First the Global Execution Context is added to the call stack and executed. Now the let and const variables get initialized and gets their assigned value stored inside the memory. And the greet function is already initialized so we move on to the line where we invoke the greet function.

Function Creation Phase

Here the call method in the function object is called which creates a new Function Execution Context.

Similar to Global Execution Context it also has the same structure and goes through two phases Creation and Execution. But this time Lexical Environment points to Function Environment Record -> Declarative Record and manages the identifier bindings for variables, parameters, function declarations etc within the function. Also we have function parameters which are added to Declarative Record and are immediately initialized with the value but the const and let variables are not.

It also has Outer Env property which points to the environment in which the function was invoked in. Which in this case is Global Environment Record (Remember in case of the Global execution Context it was null). This property will help us access values in the scope chain(meaning the outer environments).

Function Execution Phase

Now the function execution context is also added tho the call stack. To initialize the value of “fullName” it needs the parameter “firstname” and variable “lastName”. It has the identifier binding for the “firstName” but not for “lastName” so, it will use Outer Env property to look for “lastName” value through the chain of environments(scope chain).

Then the function returns and function execution context gets off the call stack. This also completes the script so the global execution context is also popped out.

console.log(name);  //undefined
var name = "Jovial"

console.log(age);  //Reference Error
let age = 19;

greet();
function greet(){
  console.log("Hello Javascript!");  // Hello Javascript
}