Understanding the Most Important JavaScript Interview Concepts in Five Minutes
Event Loop, Call Stack, Web API
Knowledge Test:
Let us examine the output generated by the following code snippet.
function callback(i) {
console.log(i)
}
for (var i = 0; i < 3; i++) {
setTimeout(() => callback(i), 1000)
}
for (let i = 0; i < 3; i++) {
setTimeout(() => callback(i), 1000)
}
How about this one?
function callback(i) {
console.log(i)
}
for (var i = 0; i < 3; i++) {
setTimeout(() => callback(i), 0)
}
for (let i = 0; i < 3; i++) {
setTimeout(() => callback(i), 0)
}
Congratulations if you managed to answer correctly. However, you might want to stick around to refresh your memory and maybe learn something new.
Even though there aren't so many lines of code in this code snippet, there are so many concepts that need to be covered in order to fully understand what is going on.
Important Concepts That will Be covered:
JavaScript is single-threaded
JavaScript is a single-threaded programming language, which means that it can only process one task at a time. Now you may ask "If JavaScript is single-threaded, How do we have the ability to execute some block of code at a later time without blocking the code execution ?" Answer: The Event Loop.
Var and Let
Hint: var is function scoped and let is blocked scope
What is the output of this code snippet?
What about this?
Answer Explanation:
The answer is 3 for the first one and ReferenceError: i is not defined for the second. But if you didn't. Here is the explanation.
Var is function scoped and let is blocked scope, but how is that helpful to know? Well, in the first code snippet, we don't have a function which means that the var value has leaked out and by the 4th iteration the value 3 terminates the for loop but because it leaks out the for loop, its value at this stage is 3. Which is the output.
Second code snippet we used the let keyword, so the value of let is scoped to that for loop, and it doesn't leak that i value, that i variable has never been declared in the main scope ( global scope ). However, the console.log lives inside the main scope and doesn't have access to the i value at all. so it throws the error ReferenceError: i is not defined.
JavaScript Call Stack
The JavaScript call stack uses a stack data structure. A stack data structure is first in, last out. Think of it as a stack of books inside a box, and to get your last book which is at the bottom of the box you will have to remove every book on top of it.
The JavaScript call stack is a stack of execution contexts, each associated with a function call. Every time a value is returned that context is popped off the stack.
function a() {
return console.log(b())
}
function b() {
console.log("Called b()")
return "you can call function a()"
}
a() // calls function a()
// OUTPUT
// Called b()
// you can call function a()
Line-by-line analysis
a() calls function a(), this creates an execution context and then this context is pushed to the stack.
Function a calls function b() and another execution context is pushed to the stack. Currently, we have two contexts.
Called b() is logged,
function b return and the execution context is popped off the stack and then finally function logs the returned value from function b "you can call function a()".
Finally, function an execution context is popped out of the stack and terminates the program.
Animations for the previous steps:
Just in case the animation doesn't work, here is the link
! [Animations for the previous steps:](https://raw.githubusercontent.com/fornonecs/advanced-javascript/main/event-loop/gifs/CallStack.gif)
Web API
There are many Web APIs and interfaces, which you can find here. However, the one that we will focus on is the set timeout.
setTimeout(() => {
// some callback
console.log("Delayed for 1 second.");
}, 1000)
The Web API has a timer running, this timer waits for the specified time limit to be finished.
After the timer has elapsed, the callback gets added to the task queue.
Task Queue
The task queue uses a queue data structure. The queue follows FIFO ( First in, first out) very similar to a queue of people waiting to get served their coffee. The first person who arrived goes first.
The JavaScript Task Queue is a queue of tasks that are waiting to be executed.
Event Loop
The event loop is an infinite loop, it keeps checking the task queue and executes the tasks when the javascript call stack is empty.
Tie Everything Together
Just in case the animation doesn't work, here is the link
! [Tie Everything Together](https://raw.githubusercontent.com/fornonecs/advanced-javascript/f501f7c15021fc62cbd7578b271f25b02b8e8251/event-loop/gifs/Event%20loop.gif)
Amazing you made it this far!
Finally, let's see if you managed to answer this correctly
What is the output of this?
function callback(i) {
console.log(i)
}
for (var i = 0; i < 3; i++) {
setTimeout(() => callback(i), 1000)
}
Notice the 1000ms and the var keyword**.**
Answer:
3
3
3
What about this?
for (let i = 0; i < 3; i++) {
setTimeout(() => callback(i), 1000)
}
Notice the 1000ms and the let keyword**.**
Answer:
0
1
2
What if we pass 0ms
What is the output of this?
console.log("Declared before setTimeout")
for (var i = 0; i < 3; i++) {
setTimeout(() => callback(i), 0)
}
console.log("log after setTimeout")
Notice the 0ms and the var keyword**.**
Answer:
"Declared before setTimeout"
"log after setTimeout"
3
3
3
console.log("Declared before setTimeout")
for (let i = 0; i < 3; i++) {
setTimeout(() => callback(i), 0)
}
console.log("log after setTimeout")
Notice the 0ms and the let keyword**.**
Answer:
"Declared before setTimeout"
"log after setTimeout"
0
1
2
Explanation:
Regardless if we pass 0ms or 1000ms to setTimeout, our callback will always go to the Web API timer and then get passed to the Task Queue.
I will be releasing more content tailored around advanced Javascript Concepts, so please follow me.
Youtube Video https://youtu.be/PTv83U2HZz4
To play with the Code all snippets are here.