Most asked Trickiest JavaScript interview question!

Jeyashri
4 min readAug 29, 2024

--

Learn about Scope, closures and asynchronous JavaScript.

Try to guess the output of the following code

Did you say 0,1,2,3,4 ?🤔

Then you are probably wrong! you may think for each loop the value of i increases by 1 and gets printed. Trust me it’s not. Don’t worry most of us get this wrong. Let’s go through the solution.

Actually the correct answer is

Before proceeding lets revise some JavaScript basics.

1.var is function-scoped meaning , var is declared once for entire function scope ,not for each iteration of the loop. So, whenever the next iteration starts the value is passed on to the current iteration from the previous iteration without creating a new variable.

2.JavaScript is single-threaded, meaning only one function executes at a time and the next starts upon the completion of the previous one.

3.Asynchronous functions in javascript have callback functions that will be executed after some asynchronus task is done.For example,setTimeout

setTimeout(function() {
console.log("Timeout Callback");
}, 0);

Here we have a asynchronous function setTimeOut which has a callback function to log “Timeout Callback” on the console after a delay of 0 milliseconds.

4.Javascript has a system to execute all of it’s functions .It has something called call stack which stores all the synchronous functions in a program and a Event queue which has all the callbacks of asynchronous functions.

So ,when a synchronous function is called it will pushed to the top of the callstack and once its executed its popped out .If the function that is called is asynchronous and has a callback the callback function will be pushed to the event queue.

Js engine executes functions in the call stack until it’s emptied .once all the main functions are executed and popped off(when the call stack becomes empty )the functions in the event queue will be executed.

Let’s say we have a JS program with two functions A and C which are synchronous and a asynschronous function with a callback function B.

// Synchronous Function A
function A() {
console.log("Function A is running.");
}

//Asynchronous Function
function asyncFunction(){
setTimeout(function B(){
console.log("Function B is running");},1000)
}

// Synchronous Function B
function C() {
console.log("Function C is running.");
}

A();
asyncFunction();
C();

Now function A and C will be stored in the callstack and function B in the event queue.

First A is called ,pushed to the top of the callstack,executed then popped out.Then when asyncFunc is called the callback function B is pushed to the eventqueue and is on hold.Then C is called,pushed to the top of the callstack,executed then popped out.Now the callstack is empty so now the tasks in the event queue will be executed(which is function B)

so the output will be,

Function A is running.
Function C is running.
Function B is running

Coming to our trickiest interview question now

function tricky(){
for(var i=0;i<5;i++){
setTimeout(
function(){
console.log(i);
},0);
}
}
tricky();

we are caliing the function tricky, it is now in the callstack,

for the 1st iteration, var i is declared and is assigned the value i=0,then comes the async function with a callback which gets pushed to the eventqueue(1).

for the 2nd iteration, since var i is function-scoped its not declared again ,previous value is passed on and incremented making i=1,then comes the async function with a callback which gets pushed to the eventqueue(2).

for the 3rd iteration i=2,then callback is pushed(3).

for the 4th iteration i=3,then callback is pushed(4).

for the 5th iteration i=4,then callback is pushed(5).

now i=5 but loop fails since the condition is false(i>5).

since call stack is now empty ,the event queue gets executed which has five callback functions to log the value of the var i. So, it prints 5 five times

5
5
5
5
5

Why var i value is carried throughout all the loops?

var i is declared in the function scope of tricky. This means that i is not block-scoped to each iteration of the loop, but rather function-scoped to tricky.

Why callbacks print value 5?

A closure is a feature in JavaScript where an inner function has access to variables from an outer function’s scope, even after the outer function has finished executing. Closures allow functions to retain access to the scope in which they were created. In the end when all the loops are done executing, the callbacks have closure to the var that was created in the function scope which has value 5 in the end.

That’s it about closures and callbacks and scopes and async! Hope this tricky interview question is no more tricky to you😉

Thankyou !

--

--