Top 15 JavaScript Interview Questions
Hello developers!!, this story is all about JavaScript. Angular /React /VueJS /NodeJS interviews will definitely have a basic JavaScript discussion. So, this story will help you in enhancing your skills in JavaScript and would make you confident enough to attend interviews. Let’s get started.
What is JavaScript?
JavaScript is a text-based blocking programming language used both on the client-side and server-side that allows you to make web pages interactive. Where HTML and CSS are languages that give structure and style to web pages, JavaScript gives web pages interactive elements that engage a user.
One of the most common questions asked in an interview is the working of JavaScript. So let’s dig a little in and see how JavaScript code works.
WORKING of JAVASCRIPT
As JavaScript is single-threaded, the execution is from top-to-bottom and executes line-by-line. So, one should understand the flow before answering any question related to JavaScript. It is highly important to look into each piece of code.
This explanation is for those who want to get a high-level understanding of how JavaScript is executed in the browser.
Part 1: What is a JavaScript Engine?
A JavaScript engine:
- Executes JavaScript.
- Implements a heap, a call stack, a message queue, and an event loop. (we’ll cover these next)
- Interacts with web APIs like
setTimeout
andsetInterval
.
JavaScript engines have historically been written to be shipped with specific browsers. Some popular examples are:
- SpiderMonkey — developed by Brendan Eich for Netscape Navigator.
- V8 — developed by Google for Chrome.
- JavaScriptCore — developed by Apple for Safari.
- Chakra — developed by Microsoft for Edge.
What is the heap?
The heap is an unstructured memory store where all memory allocation happens (e.g. storing dynamically allocated JavaScript variables).
What is the call stack?
The call stack is a data structure responsible for holding any functions that are currently executing. The call stack processes on a last-in-first-out (LIFO) basis.
The JavaScript engine will push a function onto the stack when it is invoked and pop it from the stack when it returns.
What is the message queue?
The message queue is a data structure responsible for keeping a list of messages or callbacks that are waiting to be processed by the call stack. The message queue processes on a first-in-first-out (FIFO) basis.
The message queue is populated whenever a browser event occurs and there is a listener attached to it. Clicking on an element with a click handler and using setTimeout
both fall under this category.
What is the event loop?
The event loop constantly tries to move messages from the message queue into the call stack to be processed. It does this by polling for messages in the queue and pushing them into the call stack if the call stack is empty.
Here’s a simple implementation.
Simple event loop implementation (Bowei Han, 2019)
Fun fact: the call stack can block messages from being processed from the message queue, which is why setTimeout
can take longer than its specified time to execute a callback!
For a complete understanding of the execution and breakdown look into this story.
Can we access perform file Handling using Browser-side JavaScript?
No, JavaScript doesn’t have access to writing files as this would be a huge security risk, to say the least. If you wanted to get/store information server-side, though, you can certainly make an Ajax call to a PHP/ASP/Python/etc. script that can then get/store the data in the server. If you meant to store data on the client machine, this is impossible with JavaScript alone.
If you are only trying to store a small amount of information for an unreliable period of time regarding a specific user, Web Storage API or cookies can be used.
Explain the difference between synchronous and asynchronous functions
Synchronous: Step-wise execution. Next line executed after first. Asynchronous: Execution moves to the next step before first is finished.
When you execute something synchronously, you wait for it to finish before moving on to another task. When you execute something asynchronously, you can move on to another task before it finishes.
That being said, in the context of computers this translates into executing a process or task on another “thread.” A thread is a series of commands (a block of code) that exists as a unit of work. The operating system can manage multiple threads and assign a thread a piece (“slice”) of processor time before switching to another thread to give it a turn to do some work. At its core (pardon the pun), a processor can simply execute a command, it has no concept of doing two things at one time. The operating system simulates this by allocating slices of time to different threads.
Now, if you introduce multiple cores/processors into the mix, then things CAN actually happen at the same time. The operating system can allocate time to one thread on the first processor, then allocate the same block of time to another thread on a different processor. All of this is about allowing the operating system to manage the completion of your task while you can go on in your code and do other things.
Asynchronous programming is a complicated topic because of the semantics of how things tie together when you can do them at the same time. There are numerous articles and books on the subject; have a look!
Now let’s get our hands dirty on some snippets.
Before moving on, one has to understand the sequence of execution of synchronous & asynchronous (Promise, setTimeout, etc..) codes.
Generally, the synchronous code gets executed first and then the Promise will be popped from JOB Queue and executed next and finally, the setTimout will be executed.
Assuming the time taken to complete the jobs inside async methods as 0ms, the execution will be as follows.
Note: The asynchronous behavior depends on various factors, this is for a generic one.
All Synchronous code
— FIRST execution
Promise
— NEXT execution
setTimout
— LAST execution
Q1. Find the Output of the below code
(function(){
var a = b = 3;
})();
console.log(“a defined? “ + (typeof a !== ‘undefined’)); console.log(“b defined? “ + (typeof b !== ‘undefined’));OUTPUT
a defined? false
b defined? true
Explanation
var a = b = 3
Is the same as:
var a = (b = 3)
And var
statement applies only to a
, and not to b
. You can check the syntax of var
statement here.
Therefore a
will be defined in the local scope and b
will be defined in the global scope. Inside function both a
and b
are 3 but after the function returns, registered local variable (a
) is deleted. Since b
is defined in the global scope, it is not deleted.
Q2. Find the output
console.log(1);
console.log(2);
setTimeout(()=>{console.log(3)}, 0);
console.log(4);
setTimeout(()=>{console.log(5)}, 0);
Output
1
2
4
3
5
Explanation
JavaScript is single-threaded, so it executes each line of code one by one. The control prints “1” & “2”, then when the control reaches the setTimeout() line, it pushes it to the Callback Queue in the JavaScript Engine and waits for execution. As the name suggests it is a queue that executes in the order of “FIRST-IN-FIRST-OUT”. Then the control goes to the next line and prints “4” and then again the setTimeout in the last line gets pushed to Queue. Once the execution of all synchronous code is completed, the callback queue pushes the asynchronous code to the callback stack one by one based on the time and priority. This is in general called the Event Loop. For a detailed explanation,
Q3. Find the output
var i = 0;
setTimeout(()=>{i=10},1000);while(i<=10){
console.log(i);
}
Output and Explanation
This will kill the page as the execution will not break and go into an infinite loop. For proper understanding, understand the question (Q2) in this story.
Q4. Find the output
console.log(i);
console.log(j);
var i = 10;
let j = 20;Output
undefined
VM354:2 Uncaught ReferenceError: j is not defined
Explanation
JavaScript uses hoisting for the type var
and not for the type let
. So, on the execution of the program, all variable var
declarations (not definition) are moved to the top. So line 1 prints undefined
. But with the case of let
hoisting doesn’t happen. So control throws an error.
Q5. Consider the two functions below. Will they both return the same thing? Why or why not?
function foo1() {
return {
bar: "hello"
};
}
function foo2() {
return
{
bar: "hello"
};
}
foo1();
foo2();OUTPUT
Object {bar: "hello"}
undefined
Explanation
The reason for this has to do with the fact that semicolons are technically optional in JavaScript (although omitting them is generally really bad form). As a result, when the line containing the return
statement (with nothing else on the line) is encountered in foo2()
, a semicolon is automatically inserted immediately after the return statement.
No error is thrown since the remainder of the code is perfectly valid, even though it doesn’t ever get invoked or do anything (it is simply an unused code block that defines a property bar
which is equal to the string "hello"
).
This behavior also argues for following the convention of placing an opening curly brace at the end of a line in JavaScript, rather than on the beginning of a new line. As shown here, this becomes more than just a stylistic preference in JavaScript.
Q6. Find the output
//Simple yet questionableconst numArr = [];
numArr.push(1);
numArr.push(2);
console.log(numArr);OUTPUT
(2) [1, 2]
Explanation
The documentation states:
…constant cannot change through re-assignment
…constant cannot be re-declared
When you’re adding to an array or object you’re not re-assigning or re-declaring the constant, it’s already declared and assigned, you’re just adding to the “list” that the constant points to.
Q7. Create a class and an object. The object should have a function that returns “Hello Developer!!, Hope your ass is on fire!”.
//Read the question properly. This doesn't require a parameterized constructor.class Greet {
greetUser(){
return "Hello Developer!!, Hope your ass is on fire!!";
}
}let user = new Greet();
user.greetUser();OUTPUT
"Hello World!!, Hope your ass is on fire!!"
Q8. Find the output
for(var i = 0;i<10;i++);{
console.log(i);
}for(let j = 0;j<10;j++);{
console.log(j)
}OUTPUT
10
Uncaught ReferenceError: j is not defined
EXPLANATION
This is a very easy yet tricky question. There are two things to note here. The type of variables used inside the loops and the semicolon after the loop. Hope this is self-explanatory after a short description of this question.
Q9. Find the Output
console.log(0.1 + 0.2);
console.log(0.1 + 0.2 == 0.3);OUTPUT
0.30000000000000004
false
EXPLANATION
An educated answer to this question would simply be: “You can’t be sure. it might print out 0.3
and true
, or it might not. Numbers in JavaScript are all treated with floating point precision, and as such, may not always yield the expected results.”
The example provided above is a classic case that demonstrates this issue.
Q10. Modify the given array in reverse with O(1) space complexity and with minimum Time complexity possible.
const numArr = [1, 2, 3, 4, 5, 6];
console.log(numArr);let length = numArr.length;
for(let i = 0;i< length/2;i++){
let temp = numArr[length - i - 1];
numArr[length - i -1] = numArr[i];
numArr[i] = temp;
}
console.log(numArr);OUTPUT
(6) [1, 2, 3, 4, 5, 6] //Original array
(6) [6, 5, 4, 3, 2, 1] //Modified array (Same array)
Q11. Write a add
method which will work properly when invoked using either syntax below.
console.log(add(2,3)); // Output 5
console.log(add(2)(3)); // Output 5
Solution
function add(x) {
if (arguments.length == 2) return arguments[0] + arguments[1];
else return function(y) { return x + y; };
}
Q12. Find the output
console.log(false == '0')
console.log(false === '0')OUTPUT
true
false
Explanation
= in JavaScript is used for assigning values to a variable. == in JavaScript is used for comparing two variables, but it ignores the data type of the variable. === is used for comparing two variables, but this operator also checks datatype and compares two values.
Q13. Write a simple Promise method with more than one catch blocks.
//This is to test the knowledge of what you have learned so far.let fetchData = new Promise((resolve, reject)=>{
reject('Ah crap!');
}).catch((reason)=>{
console.log("From catch block 1, ", reason);
throw reason;
}).catch((reason)=>{
console.log("From catch block 2, ", reason);
});OUTPUT
From catch block 1, Ah crap!
From catch block 2, Ah crap!
EXPLANATION
Self-explanatory.
(continuation) Q13.1 What will happen if you execute fetchData
?
fetchData.then((res)=>{
console.log("Promise Fulfilled!")
})OUTPUT
Promise Fulfilled!
EXPLANATION
Promise takes a callback function that has two parameters resolve
and reject
. When the Promise is invoked, it returns Promise {<fulfilled>: undefined}
. According to the invoker fetchData, the Promise execution is completed. So it prints “Promise Fulfilled” in the console.
Q14. Find the first and last index of a number in the given array. If it is not found return -1;
//target = 3
const numArr = [1, 2, 3, 4, 5, 1, 2, 3];SOLUTIONconsole.log("First Index: " + numArr.indexOf(3), "Last Index: " + numArr.lastIndexOf(3))OUTPUT
First Index: 2 Last Index: 7
Q15. Find the Output
console.log(1 < 2 < 3);
console.log(3 > 2 > 1);OUTPUT
true
false
EXPLANATION
1 < 2 < 3
can be broken down as (1<2) < ((1<2) < 3)),
1<2 is true.
(1<2) < 3 can be written as ,
(true) < 3
(1) < 3 //True is basically 1 and false is 0
trueOUTPUT
true
(3 > 2 > 1)
can be broken down as (3>2) > ((3>2) > 1))
3>2 is true.
(3>2) > 1 can be written as,
(true) > 1
(1) > 1 //True is basically 1 and false is 0
falseOUTPUT
false
These are some high-priority questions available. For more like this take a look at,
CONCLUSION
Remember, a wise man once said,
It is easy to confuse “What if” with “What ought to be” especially when “What if” has worked out in your favor.
Hey! If you enjoyed this post, leave a comment below, and please share it with a friend who you think might find it helpful too. Thanks for reading!
Happy Coding!! ♥