Given this code snippet, it invokes a function greeting, which in turn invokes an async function setTimeOut. After two seconds, we then execute an anonymous function.
|
function greeting() { var name = "Bob"; setTimeOut( function() { console.log(`Hello ${name}`); }, 2000); } greeting(); |
Let’s see how this works in memory.
When the program starts up, the global context is invoked. When something is invoked, it goes through creation and execution phase.
Global context Creation Phase:
– this reference the global object
– outer scope is set
– stores ‘greeting’ function into memory. Thus hoisting it.

In Global context Execution Phase, we start executing each line of code. We see the definition of the greeting, we move on. We then see greeting is invoked. We push that onto the execution context.

When a new context is pushed onto the execution context we have to process its creation phase and execution phase.
So do this for greeting function.
Greeting Creation Phase:
– this references global object
– sets up outer references
– puts variable name in memory and assign it to undefined

Greeting Execution Phase:
We see that variable ‘name’ gets assigned to “Bob”.
We then invoke setTimeOut function. Its definition is already in the JS library.
Thus we push setTimeOut context onto the main execution context.

Whenever a new context is pushed, we have to process its creation and execution phase.
setTimeOut Creation Phase:
setTimeOut has parameter which is an anonymous function. We put that into memory.

Because setTimeOut is an async function, it may need to be running even if its parent function has been popped from the execution stack. So in order to remedy this, it gets put into memory.

Now that the creation phase of setTimeOut is done, we continue with setTimeOut’s Execution Phase.
It executes starts running its timer for two seconds. Because this function is running async, we continue executing down the line even though the timer is still running. We get to the end of ‘greeting’ and its context pops from the execution stack.

However, even though ‘greeting’ has popped, notice that its variable ‘name’ has not. This is because the callback anonymous function we put into memory references that ‘name’ in its console log statement. Hence, we keep greeting’s name variable in memory.
Two seconds later, the timer is done. The anonymous function then gets pushed onto a queue called The Callback queue
Because the execution stack is empty (no other custom function or Web-based functions are running), we are then able to push our callback function from the Callback queue and onto the execution stack.

As with any new invocations on the execution stack, we must go through Creation and Execution phase.
During the creation phase, the ‘this’ reference is set to TimeOut object because setTimeOut is a reference to a function constructor object TimeOut. There are no parameters, declared variable(s), or function definitions to be placed in memory.
In the execution phase, we start executing the console log statement. It calls on the name variable. That name takes on the value from greeting’s name variable which is currently pointing to Bob. Thus, the anonymous function’s name points to string literal “Bob”.
When we’re done, the anonymous function pops, along with its variable name because no other is referencing them. Since callback of setTimeOut(callback) has been garbage collected, setTimeOut itself has nothing to do in memory so it gets garbage collected as well.
Greeting definition is still in memory because it was previously defined and needs to be used. Its variable ‘name’ is not used by anyone so it will eventually be garbage collected as well.

Async operation explained generally
|
function first() { console.log("Hey There"); second(); console.log("The End"); } function second() { setTimeout(()=> { console.log("hohoho"); }, 2000); } first(); |
1) We execute function first and push it onto the stack.
2) We then execute the log function and print “Hey There”.
1) logging finishes and gets popped. Our string gets garbage collected from memory
2) function second gets executed and pushed onto the stack.

1) setTimeout gets pushed because it was executed.
2) Because it runs asynchronously, it gets put into a different part of memory reserved for async operations
1) function seconds finishes and pops
2) log “The End” gets pushed onto the stack

Logging of “The End” gets popped from stack.
function first gets popped from the stack.
“The End” gets garbage collected from the heap.
Our async operation finishes, and the callback function gets pushed onto a “Callback Queue”.

We see that the stack is empty. Thus, we can push our callback function onto the stack to be executed.

The callback function executes. We push the log function onto the stack. Its string gets moved to the heap.
We then print.
Then the string literal gets garbage collected.
The log function gets popped,
The callback function gets popped,
and everything returns to empty.
