2021 JavaScript Interview Questions and Answers - IQCode

Javascript Interview Questions

Here are some common questions that may come up during a Javascript interview:

// Sample code can be added here.

Introduction to JavaScript

JavaScript, developed by Brendan Eich in 1995, is a highly popular language used for web development. Originally designed for creating dynamic web pages, each JS program or script can be attached to any HTML webpage and runs automatically when the page loads. While it was initially used only for client-side scripting, it can now be executed on the server and on virtually any device equipped with a JavaScript Engine. In this tutorial, we will answer some of the most frequently asked JavaScript interview questions to help you learn this valuable programming language.

(this space intentionally left blank as there is no code to include in this introduction)


1. What are the different data types present in JavaScript?
2. Explain Hoisting in JavaScript.
3. What is the difference between “==” and “===” operators in JavaScript?
4. Explain Implicit Type Coercion in JavaScript.
5. Is JavaScript a statically typed or a dynamically typed language?
6. What is NaN property in JavaScript?
7. Explain pass by value and pass by reference in JavaScript.
8. What is an Immediately Invoked Function in JavaScript?
9. Explain Higher Order Functions in JavaScript.
10. Explain “this” keyword in JavaScript.
11. Explain call(), apply() and bind() methods in JavaScript.
12. What is Currying in JavaScript?
13. Explain Scope and Scope Chain in JavaScript.
14. Explain Closures in JavaScript.
15. What are object prototypes in JavaScript?
16. What are callbacks in JavaScript?
17. What is Memoization in JavaScript?
18. What is Recursion in JavaScript?
19. What is the use of a constructor function in JavaScript?
20. What is DOM in JavaScript?

// Example:

function constructPerson(name, age) {
  this.name = name;
  this.age = age;

const person = new constructPerson('John', 32);
console.log(person.name); // Output: John

Advanced JavaScript Interview Questions

//1. Arrow Functions
//Arrow functions are a shorthand way of writing functions in JavaScript. They are also known as lambda functions in other languages.
const greet = name => {
  console.log(`Hello, ${name}!`);
greet("John"); // Output: "Hello, John!"

//2. Differences between var, let, and const
//In JavaScript, variables can be declared using var, let, or const. The main differences between them are their scoping rules and whether they can be reassigned.
//var has function scope and can be reassigned.
//let has block scope and can be reassigned.
//const has block scope and cannot be reassigned.
function testVar() {
  var x = 1;
  if (true) {
    var x = 2;
    console.log(x); // Output: 2
  console.log(x); // Output: 2

function testLet() {
  let x = 1;
  if (true) {
    let x = 2;
    console.log(x); // Output: 2
  console.log(x); // Output: 1

const x = 1;
// x = 2; // Error: Assignment to constant variable.

//3. Rest Parameter and Spread Operator
//The rest parameter allows a function to accept an indefinite number of arguments as an array. The spread operator allows an array to be expanded into individual arguments.
function sum(...args) {
  return args.reduce((total, num) => total + num);
console.log(sum(1,2,3)); // Output: 6

const arr1 = [1,2,3];
const arr2 = [4,5,6];
const arr3 = [...arr1, ...arr2];
console.log(arr3); // Output: [1,2,3,4,5,6]

//4. Promises
//Promises are a way to handle asynchronous operations in JavaScript. They represent a value that may not be available yet, but will be resolved in the future.
const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("Hello, world!");
  }, 2000);
promise.then(message => console.log(message)); // Output after 2 seconds: "Hello, world!"

//5. Classes
//Classes are a way to define objects in JavaScript. They are syntactic sugar over the existing prototype-based inheritance model.
class Person {
  constructor(name) {
    this.name = name;
  greet() {
    console.log(`Hello, my name is ${this.name}.`);
const person = new Person("John");
person.greet(); // Output: "Hello, my name is John."

//6. Generator Functions
//Generator functions are a way to define iterators in JavaScript. They allow a function to pause and resume its execution at any time.
function* generateSequence() {
  yield 1;
  yield 2;
  yield 3;
const sequence = generateSequence();
console.log(sequence.next().value); // Output: 1
console.log(sequence.next().value); // Output: 2
console.log(sequence.next().value); // Output: 3

//7. WeakSet
//WeakSet is a collection that allows only objects as its members. It is similar to Set, but it has weaker references to its members, making them eligible for garbage collection.
let john = {name: "John"};
const weakSet = new WeakSet();
john = null; // john object is now eligible for garbage collection

//8. WeakMap
//WeakMap is a collection that allows objects only as keys and arbitrary values. It is similar to Map, but it has weaker references to its keys and values, making them eligible for garbage collection.
let john = {name: "John"};
const weakMap = new WeakMap();
weakMap.set(john, "example value");
john = null; // john object is now eligible for garbage collection

//9. Object Destructuring
//Object destructuring is a way to extract properties from an object and assign them to individual variables.
const obj = {x: 1, y: 2};
const {x, y} = obj;
console.log(x); // Output: 1
console.log(y); // Output: 2

//10. Temporal Dead Zone
//Temporal dead zone refers to the time between the creation of a variable and its declaration where it can't be accessed. This is due to variables declared with let and const having block scope.
console.log(x); // Output: undefined
let x = 1;

Basic JavaScript Interview Questions:

// This is an example of how to declare a function
function multiplyNumbers(num1, num2) {
  return num1 * num2;

// Here is an example of function call
var result = multiplyNumbers(3, 5);
console.log(result); // It will log 15 on the console

// This is an example of how to declare a variable
var myVariable = "Hello World";

// This is an example of how to check if a variable is defined or not
if (typeof myVariable !== "undefined") {
  console.log(myVariable); // It will log "Hello World" on the console

// This is an example of how to loop through an array using for...of loop
var myArray = [1, 2, 3];
for (var element of myArray) {
  console.log(element); // Will log 1, 2, 3 on the console

Different Data Types in JavaScript

JavaScript supports various data types. We can use the `typeof` operator to determine the type of a JavaScript variable.

## Primitive Data Types

### String

A string represents a series of characters. It can be written using single or double quotes.


const str = "John Singh Bisht"; // using double quotes
const str2 = 'John Doe'; // using single quotes

### Number

A number represents a numerical value. It can be written with or without decimals.


const x = 3; // without decimal
const y = 3.6; // with decimal

### BigInt

A BigInt is used to store numbers beyond the limitation of the `Number` data type. It can store large integers and is represented by adding "n" to an integer literal.


const bigInteger = 234567890123456789012345678901234567890n;

### Boolean

A boolean represents a logical entity and can have only two values: `true` or `false`. Booleans are generally used for conditional testing.


const a = 2;
const b = 3;
const c = 2;
(a == b); // returns false
(a == c); // returns true

### Undefined

If a variable is declared but not assigned a value, it has the value of `undefined` and its type is also `undefined`.


let x; // value of x is undefined
const y = undefined; // we can also set the value as undefined

### Null

A null value represents a non-existent or invalid value.


const z = null;

### Symbol

A symbol is a new data type introduced in ES6. It is used to store an anonymous and unique value.


const symbol1 = Symbol('symbol');

### typeof of Primitive Types

- `string` - `number` - `boolean` - `bigint` - `undefined` - `object` (typeof null) - `symbol`

## Non-Primitive Data Types

Primitive data types store only a single value. To store multiple and complex values, non-primitive data types are used.

### Object

Objects are used to store collections of data in key-value pairs or as an ordered list.


// collection of data in key-value pairs

const obj1 = {
   x:  43,
   y:  "Hello world!",
   z: function(){
      return this.x;

// collection of data as an ordered list

const array1 = [5, "Hello", true, 4.1];

It is important to remember that any data type that is not a primitive data type is of object type in JavaScript.

Understanding Hoisting in JavaScript

Hoisting is a fundamental behavior of JavaScript where the function and variable declarations are moved to the top of their respective scopes. Regardless of where they are declared, they will be moved to the top. Scopes can be local or global.

Example 1:

var hoistedVariable;
hoistedVariable = 3;
console.log(hoistedVariable); // outputs 3 since the variable is hoisted

Example 2:

hoistedFunction(); // Outputs "Hello world!"

function hoistedFunction(){
   console.log("Hello world!");

Example 3:

function doSomething(){
  var x;
  x = 33;
doSomething(); // Outputs 33

Note that variable initializations are not hoisted, only variable declarations are hoisted.

var x;
console.log(x); // Outputs undefined because the initialization of "x" is not hoisted
x = 23;

To prevent hoisting, you can use "use strict" at the top of the code.

"use strict";
var x;
x = 23; // Throws an error since 'x' is not declared

Difference Between "==" and "===" Operators

In JavaScript, both "==" and "===" are comparison operators used to compare values. However, the main difference between them is that "==" only compares the values, while "===" compares both the values and the types.

Here's an example:

var x = 2;
var y = "2";

// Compares the value of x and y only
console.log(x == y);  // Returns true

// Compares both the value and type of x and y
console.log(x === y); // Returns false

In the first comparison, "==" returns true because it only checks that the values of x and y are the same, even if one is a string and the other is a number. In contrast, the second comparison using "===" returns false because it checks that both the value and the type of x and y are the same.Explanation of Implicit Type Coercion in JavaScript

H3 tag: Implicit Type Coercion in JavaScript

In JavaScript, implicit type coercion is the automatic conversion of a value from one data type to another. This process happens when the operands of an expression are of different data types. Implicit type coercion can occur in various situations, such as when using logical operators, if statements and loop checks, equality comparison using the '==' operator, and concatenation of strings.

1. String Coercion

String coercion occurs when a number is added to a string using the '+' operator. In this case, the number type is always converted to the string type. For example:

var x = 3;
var y = "3";
console.log(x + y); // Outputs "33"

Similarly, when concatenating two strings using the '+' operator, the output is a concatenated string. For example:

var name = "John";
var surname = "Bisht";
console.log(name + surname); // Outputs "John Bisht"

2. Boolean Coercion

In JavaScript, truthy values are those that will be converted to `true`, whereas falsy values are those that will be converted to `false`. Boolean coercion occurs when using logical operators, if statements and loop checks. For example:

var x = 0;
var y = 23;

if(x) { console.log(x) } // The code inside this block will not run since the value of x is 0 (falsy)

if(y) { console.log(y) } // The code inside this block will run since the value of y is 23 (truthy)

3. Equality Coercion

Equality coercion takes place when using '==' operator. The '==' operator compares values and not types. In this case, both operands are converted to the same type and then compared. The '===' operator, on the other hand, does not perform any type coercion. For example:

var a = 12;
var b = "12";
console.log(a == b); // Outputs true because both 'a' and 'b' are converted to the same type and compared.

console.log(a === b); // Outputs false because the operands are of different types and no coercion takes place.

With an understanding of implicit type coercion, a JavaScript developer can write safer and more robust code.

Is Javascript a statically or dynamically typed language?

JavaScript is a dynamically typed language, meaning that variable types are checked during runtime rather than compile-time. In contrast to statically typed languages, variables in JS are not assigned a specific type. This means that a variable can hold any data type. For example, a variable which is initially assigned a number type can later be assigned a string type:

let a = 23;
a = "Hello World!";

Explanation of NaN Property in JavaScript

NaN property represents a value which is not a legal number and stands for "NOT-A-NUMBER". The typeof operation on NaN will return 'number', which might seem strange at first. To check if a value is NaN, we use the isNaN() function. It checks if the given value is not a number.

It is important to note that when the isNaN() function is called, the given value is first converted to a number type, and then equated to NaN. Therefore, if you pass a non-numeric string as an argument, the isNaN() function will return true, even though the string does not represent NaN.

Here are some examples:

isNaN("Hello")  // Returns true
isNaN(345)   // Returns false
isNaN('1')  // Returns false, since '1' is converted to a Number type which results in 1 (a number) 
isNaN(true) // Returns false, since true converted to Number type results in 1 (a number)
isNaN(false) // Returns false, since false converted to Number type results in 0 (a number)
isNaN(undefined) // Returns true

As you can see from the above examples, isNaN() returns true for non-numeric strings and undefined values. It's important to use isNaN() function to determine whether a value is a legal number or not.

Passed by Value and Passed by Reference in JavaScript

In JavaScript, primitive data types are passed by value and non-primitive data types are passed by reference. When we create a variable and assign a value to it, the assign operator allocates space in memory, saves the value, and returns the location of the allocated memory space. As a result, the variable points to the allocated memory space instead of the actual value.

In the case of primitive data types, when one variable is assigned to another, the assign operator allocates new memory and returns its address for the new variable. Therefore, two variables of the same primitive data type have different address locations even if they contain the same value.

However, in non-primitive data types, the assign operator directly passes the location of the original variable to the new variable. Therefore, both variables point to the same address. Hence, if we change the value of the original variable, the value of the other variable changes as well since they point to the same address.

Here is an example of how passing by value and passing by reference works:

Passed by Value:

var num1 = 10;
var num2 = num1;

console.log(num2); // Output: 10

num1 = 5;

console.log(num1); // Output: 5
console.log(num2); // Output: 10

In the above example, num1 and num2 are both primitive data types (numbers), so the value of num1 is assigned to num2. Therefore, num2 is now assigned a new memory location that has the same value of num1. When we change the value of num1, the value of num2 remains intact.

Passed by Reference:

var obj1 = { name: "John", age: 30 };
var obj2 = obj1;

console.log(obj2); // Output: { name: "John", age: 30 }

obj1.name = "Jane";

console.log(obj1); // Output: { name: "Jane", age: 30 }
console.log(obj2); // Output: { name: "Jane", age: 30 }

In the above example, obj1 and obj2 are both non-primitive data types (objects), so when obj1 is assigned to obj2, obj2 points to the same memory space as obj1. Therefore, changing the value of obj1 also changes the value of obj2 since they both have the same memory location.

What is an Immediately Invoked Function in JavaScript?

An Immediately Invoked Function, also known as an IIFE (pronounced "iffy"), is a function that runs as soon as it is defined. The syntax for an IIFE is:

  // Do something;

To understand IIFE, it is important to understand the two sets of parentheses that are used while creating an IIFE. The first set of parentheses is used to tell the compiler that the function is not a function declaration, but a function expression. For example:

  // Do something;

The second set of parentheses is used to invoke the function. If we do not use the second set of parentheses, the function declaration is simply returned and not executed. For example:

  // Do something;
}) // Returns the function declaration

Overall, IIFEs are useful for creating code that is isolated from the global scope and for avoiding naming collisions. They are commonly used in modular JavaScript design patterns.

Explanation of Higher Order Functions in JavaScript

In JavaScript, functions can be considered as first-class citizens. This means that functions behave like any other value in the language. Higher order functions are functions that take other functions as arguments or return functions as values.

An example of a higher order function that takes another function as an argument is:

function higherOrder(fn) { fn(); } higherOrder(function() { console.log("Hello world") });

In this example, the higherOrder function takes a function as an argument and then executes it.

An example of a higher order function that returns a function is:

function higherOrder2() { return function() { return "Do something"; } } var x = higherOrder2(); x() // Returns "Do something"

In this example, the higherOrder2 function returns a new function that simply returns the string "Do something" when called.

By using higher order functions, we can write more flexible and reusable code since we can pass different functions as arguments and return different functions as values depending on the situation.

Understanding the "this" keyword in JavaScript

The "this" keyword refers to the object that the function is a property of. The value of the "this" keyword will always depend on the object that is invoking the function. Let's look at some examples to understand this better.

Example 1:

function doSomething() {

In this example, since we are invoking the function in the global context, the "this" keyword will refer to the global object, which is the window object in the browser.

Example 2:

var obj = {
    name: "vivek",
    getName: function(){

In this example, since the getName function is a property of the object "obj" at the time of invocation, the "this" keyword will refer to the object "obj", and hence the output will be "vivek".

Example 3:

var obj = {
    name: "vivek",
    getName: function(){
var getName = obj.getName;
var obj2 = {name:"akshay", getName };

In this example, although the getName function is declared inside the object "obj", at the time of invocation, "getName()" is a property of obj2, and hence the "this" keyword will refer to obj2. The output will be "akshay".

A simple way to understand the "this" keyword is to look at the object before the dot when the function is invoked. The value of the "this" keyword will always be the object before the dot. If there is no object before the dot like in example 1, the value of "this" keyword will be the global object.

Example 4:

var obj1 = {
    address : "Mumbai,India",
    getAddress: function(){
var getAddress = obj1.getAddress;
var obj2 = {name:"akshay"};

In this example, although the "this" keyword refers to the object "obj2", obj2 does not have the property "address", hence the "getAddress" function throws an error.

Explanation of Call(), Apply(), and Bind() Methods

Call(): It is a built-in method in JavaScript that invokes a function by specifying the object that owns the method. This method allows one object to use methods of another object. For example:

function sayHello() {
  return "Hello " + this.name;

var obj = {name: "Sandy"};


// Returns "Hello Sandy"

The call() method can also accept arguments, like so:

function saySomething(message) {
  return this.name + " is " + message;

var person = {name: "John"};

saySomething.call(person, "awesome");

// Returns "John is awesome"

Apply(): The apply() method is similar to the call() method, with the only difference being that call() method takes arguments separately, whereas apply() method takes arguments as an array. For example:

function saySomething(message) {
  return this.name + " is " + message;

var person = {name: "John"};

saySomething.apply(person, ["awesome"]);

Bind(): The bind() method returns a new function with its "this" keyword bound to the owner object provided as a parameter. It is useful when you want to pass a method as a callback function that needs the correct reference to "this". For example:

var bikeDetails = {
  displayDetails: function(registrationNumber,brandName){
    return this.name + ", bike details: " + registrationNumber + ", " + brandName;

var person1 = {name: "John"};

var detailsOfPerson1 = bikeDetails.displayDetails.bind(person1, "TS0122", "Bullet");

// Binds the displayDetails function to the person1 object


// Returns "John, bike details: TS0452, Thunderbird"

Currying in JavaScript

Currying is an advanced technique used to transform a function with arguments N to N functions, each taking one or fewer arguments. Here's an example of a curried function:

function add(a) {
  return function(b) {
    return a + b;


Essentially, currying enables us to transform a function with multiple arguments into a series of functions that each take only one argument. The functionality of the original function is preserved, and we simply change the way we invoke it.

Here's an example of currying in action:

function multiply(a, b) {
  return a * b;

function currying(fn) {
  return function(a) {
    return function(b) {
      return fn(a, b);

var curriedMultiply = currying(multiply);

multiply(4, 3); // returns 12

curriedMultiply(4)(3); // also returns 12

In this example, we transformed the function 'multiply(a, b)' into a function called 'curriedMultiply', which takes one parameter at a time.

Understanding Scope and Scope Chain in JavaScript

Scope in JavaScript refers to the accessibility of variables and functions in different parts of the code. It determines where certain variables and functions can be accessed and used in the code. JavaScript has three types of scopes which include Global Scope, Local or Function Scope, and Block Scope.

Global Scope variables or functions that are declared in the global namespace are accessible from anywhere in the code.


var globalVariable = "Hello, world";

function sendMessage(){
  return globalVariable; 

function sendMessage2(){
  return sendMessage(); 

sendMessage2(); // Returns “Hello world”

In the example above, `globalVariable` is available throughout the entire code, including both functions `sendMessage` and `sendMessage2`.

On the other hand, Local or Function Scope pertains to variables or functions declared in a function and can only be accessed within that function.


function awesomeFunction(){
  var a = 2;

  var multiplyBy2 = function(){
    console.log(a * 2); 

In this example, `a` and `multiplyBy2` are only accessible within the `awesomeFunction` since it is where they were declared. Trying to access these variables outside of the function will throw a reference error.

Lastly, Block Scope pertains to variables declared using let and const. Variables under block scope can only be accessed within the block where they were declared.


  let x = 45;

console.log(x); // Throws reference error since `x` cannot be accessed outside of the block

Overall, understanding the different scopes in JavaScript is essential in controlling the privacy of variables and functions in the code.

Explanation of Closures in JavaScript

Closures in JavaScript refer to the ability of a function to remember the functions and variables that are defined in its outer scope. Let's look at an example below to further understand closures:


var Person = function(personName){
    var name = personName;

    this.getName = function(){
        return name;

var person = new Person("Jane");

In the code above, the `Person` function is declared with a parameter `personName`. A variable `name` is declared in the function and it is set to the value of `personName`. The `getName()` function is declared inside the `Person` function and it returns the value of `name`. A new `Person` object is instantiated with the `personName` parameter set to "Jane". The `console.log()` function is called which will output "Jane" in the console log.


function randomFunc(){
    var obj1 = {name:"Vivian", age:45};
    return function(){
        console.log(obj1.name + " is " + "awesome");

var initialiseClosure = randomFunc();

In the code above, the `randomFunc()` function is declared and a variable `obj1` is declared too. `obj1` is an object that has two properties, `name` and `age`. A function is returned that uses the `obj1.name` variable and outputs a string with that variable. `initialiseClosure` is assigned to `randomFunc()`. When `initialiseClosure()` is called, it will output "Vivian is awesome".

The function `randomFunc()` is executed and it returns a function. Instead of `randomFunc()` destroying the `obj1` variable after execution as one might expect, it stores the variable in memory for further reference. Therefore, when the returned function is executed, it can access the variable that was declared in its outer scope. This ability of a function to store a variable for further reference even after it is executed is what defines a closure in JavaScript.

Understanding Object Prototypes in JavaScript

In JavaScript, object prototypes are a way for objects to inherit properties from a parent prototype. This means that Date objects will inherit from the Date prototype and Array objects will inherit from the Array prototype. At the top of the prototype chain is Object.prototype, which all prototypes inherit from. Essentially, a prototype is like a blueprint for an object.

Prototypes allow us to use methods and properties on an object, even if they do not exist on the current object. For instance, in the code below, we are able to use the method "push" on the array "arr," despite not defining it:

    var arr = [];
    console.log(arr); // Outputs [2]

This is because JavaScript's engine automatically looks for the method in the Array prototype when it's not found in the current object. If it still doesn't exist, it continues to look in the prototype's prototype and so on, until it finds it or reaches the end of the chain.

Essentially, using objects and their prototypes in JavaScript allows for more efficient programming and minimized code repetition.

Understanding Callback Functions in JavaScript

A callback function is a function that executes after another function has finished executing. In JavaScript, functions are first-class citizens, meaning they can be used as arguments or returned by other functions and can be properties of an object. A callback function that is used as an argument to another function is known as a callback function. An example of these is:

function divideByHalf(sum){
  console.log(Math.floor(sum / 2));

function multiplyBy2(sum){
  console.log(sum * 2);

function operationOnSum(num1,num2,operation){
  var sum = num1 + num2;

operationOnSum(3, 3, divideByHalf); // Outputs 3

operationOnSum(5, 5, multiplyBy2); // Outputs 20

In the code, mathematical operations are performed on the sum of two numbers. The `operationOnSum` function takes three arguments, the first number, the second number, and the operation to be performed on their sum. The `divideByHalf` and `multiplyBy2` functions are used as callback functions in the code above. These callback functions only execute once the `operationOnSum` function has completed executing. Thus, a callback function is a function that executes after another function has finished executing.

Understanding Memoization in JavaScript

Memoization is a caching technique that stores the return value of a function based on its parameters. It helps to avoid the computation of already computed values for the same set of parameters. In JavaScript, the process of converting a normal function to a memoized version is simple, let's understand it better with an example.

Consider the following example:

function addTo256(num){
  return num + 256;

addTo256(20); // Returns 276
addTo256(40); // Returns 296
addTo256(20); // Returns 276

In this code, we have a simple function that adds a parameter to 256 and returns the result. As you can see, the result is computed multiple times for the same parameter. However, for a simple function like this, it's not a big deal. But if this function performs some complex computations, then computing the result repeatedly will lead to wastage of time.

Memoization helps to solve this problem by caching the computed result of the function based on its parameter. If the same parameter is used again while invoking the function, instead of computing the result again, it returns the stored (cached) value.

Let's convert the above function to a memoized function:

function memoizedAddTo256(){
  var cache = {};

  return function(num){
    if(num in cache){
      console.log("cached value");
      return cache[num];
      cache[num] = num + 256;
      return cache[num];

var memoizedFunc = memoizedAddTo256();

memoizedFunc(20); // Normal return
memoizedFunc(20); // Cached return

In the above code, we have converted the function `addTo256` to a memoized function (`memoizedAddTo256`) that uses caching to store the computed result. We have created a cache object that stores the result and checks whether a value exists in the cache or not. If it is already available in the cache, it returns the cached result; otherwise, it stores the result in the cache and returns it.

Memoization is a useful technique for expensive function calls, and it improves the performance of the application. But it also results in larger memory consumption because it stores all the computed results.

Understanding Recursion in Programming

Recursion refers to the process of a function calling itself repeatedly until it arrives at a solution or result. It is a useful technique when dealing with repetitive tasks or problems that can be broken down into smaller sub-problems.

Here is an example of a recursive function that adds numbers in a sequence:


function addNumbers(num) {
  if (num === 0) {
    return 0;
  } else {
    return num + addNumbers(num - 1);
console.log(addNumbers(3)); // returns 6

In the above code, the `addNumbers` function takes a number as input and checks if it is equal to 0. If it is, the function returns 0. Otherwise, it calls itself again with the input value decremented by 1, and adds the current value of `num` to the result. This process continues until the input value reaches 0, and the function returns the sum of all the numbers in the sequence.

Another example of a recursive function is one that calculates the sum of all the elements in an array:


function computeSum(arr){
  if(arr.length === 1){
    return arr[0];
    return arr.pop() + computeSum(arr);

console.log(computeSum([7, 8, 9, 99])); // returns 123

In the above code, the `computeSum` function takes an array as input and checks if the length of the array is equal to 1. If it is, the function returns the value at index 0 of the array. Otherwise, the function calls itself with the array minus its last element, and adds the last element to the result. This process continues until there is only one element left in the array, and the function returns the sum of all the elements.

Recursion is a powerful and elegant way to solve complex problems in programming, but it should be used with care as it can lead to performance issues if not optimized correctly.

What is the purpose of a constructor function in JavaScript?

In JavaScript, constructor functions are used to create objects. They're used when we want to create multiple objects with similar properties and methods.

Note: The name of a constructor function should always be written in Pascal notation, with the first letter of every word capitalized.

For example:

function Person(name, age, gender){
  this.name = name;
  this.age = age;
  this.gender = gender;

var person1 = new Person("John", 76, "male");

var person2 = new Person("Courtney", 34, "female");

In the code above, we've created a constructor function named Person. Whenever we want to create a new object of this type, we need to use the new keyword:

var person3 = new Person("Lilly", 17, "female");

This will create a new object of the type Person. Constructor functions allow us to group similar objects together.

Understanding the Document Object Model (DOM)

The Document Object Model (DOM) is a programming interface specifically designed for HTML and XML documents. When a browser attempts to render an HTML document, it creates a tree-like object known as the DOM, which contains all the elements of the document.

Using the DOM, we can perform operations like adding, removing or modifying elements and their attributes in an HTML document. This makes it easier for developers to manipulate the structure and content of web pages using JavaScript.

For instance, when you create an HTML page that contains elements like text, images, buttons, and inputs, each of these elements is represented as a node in the DOM tree. By modifying the properties and attributes of these nodes, you can dynamically update the contents and appearance of the web page.

Overall, understanding the DOM is an important prerequisite for any developer working with JavaScript and web development.

Overview of Arrow Functions in JavaScript

Arrow Functions are a shorthand syntax for writing functions in javascript. They were introduced in the ES6 version of javascript and provide a shorter, more concise way of declaring functions. In traditional function expressions, the function keyword is used to declare a function with a separate block of code, whereas in arrow functions, there is no need for the function keyword.

Here are some examples:

  // Traditional Function Expression
  var add = function(a,b){
    return a + b;
  // Arrow Function Expression
  var arrowAdd = (a,b) => a + b;
  // Traditional function expression
  var multiplyBy2 = function(num){
    return num * 2;
  // Arrow function expression
  var arrowMultiplyBy2 = num => num * 2;
  var obj1 = {
    valueOfThis: function(){
      return this;
  var obj2 = {
    valueOfThis: ()=>{
      return this;

Arrow functions offer a concise syntax for functions that take only one argument. The parentheses around the parameter can be omitted if only one argument is passed. If the function has only one statement, the curly braces can also be omitted.

A key difference between traditional functions and arrow functions is their handling of the ‘this’ keyword. In traditional functions, the ‘this’ keyword refers to the object that is calling the function, whereas in arrow functions, the ‘this’ keyword does not refer to the object calling the function. Instead, it inherits its value from the parent scope, which in this case is the window object.

It is important to keep this difference in mind while using arrow functions to avoid any unexpected errors.

Differences Between Declaring Variables Using Var, Let, And Const

Before ES6, the `var` keyword was used for declaring variables. With the introduction of ES6, the `let` and `const` keywords were introduced for declaring variables.

Here are the differences between var, let, and const:

Keyword const let var
Global scope no no yes
Function scope yes yes yes
Block scope yes yes no
Can be reassigned no yes yes

Let's understand the differences with examples:

var variable1 = 23;

let variable2 = 89;

function catchValues() {
  // Both the variables can be accessed anywhere since they are declared in the global scope

window.variable1; // Returns the value 23
window.variable2; // Returns undefined

The variables that are declared with the `let` keyword in the global scope behave just like the variables declared with the `var` keyword in the global scope. Variables declared in the global scope with both `var` and `let` keywords can be accessed from anywhere in the code. However, there is one difference: variables declared with the `var` keyword in the global scope are added to the `window` or `global` object, so they can be accessed using `window.variableName`. However, variables declared with the `let` keyword are not added to the global object, so trying to access such variables using `window.variableName` results in an error.

function varVsLetFunction() {
  let awesomeCar1 = "Audi";
  var awesomeCar2 = "Mercedes";

console.log(awesomeCar1); // Throws an error
console.log(awesomeCar2); // Throws an error

Variables declared in a local or functional scope using both `var` and `let` keywords behave the same, meaning that they cannot be accessed from outside of the scope.

  var variable3 = [1, 2, 3, 4];

console.log(variable3); // Outputs [1, 2, 3, 4]

  let variable4 = [6, 55, -1, 2];

console.log(variable4); // Throws an error

for(let i = 0; i < 5; i++) {
  // Does something

In conclusion, `let` and `const` offer better variable scope and less complexity in code. In general, `const` must be used if the value of a variable will not change, and `let` should be treated as the new `var` for declaring variables.REST PARAMETER AND SPREAD OPERATOR IN JAVASCRIPT

In ES6 version of Javascript, both the rest parameter and spread operator were introduced. The REST PARAMETER (…) provides an improved way of handling function parameters, allowing us to create functions that can take a variable number of arguments. Any number of arguments can be converted into an array using the rest parameter, which can also help in extracting some or all parts of the arguments.

To use the rest parameter, apply three dots (…) before the parameters:

function extractArgs(...args){
  return args[1];
// extractArgs(8, 9, 1) returns 9

function addAllArgs(...args){
  let sumOfArgs = 0;
  let i = 0;
  while(i < args.length) {
    sumOfArgs += args[i];
  return sumOfArgs;
// addAllArgs(8, 9, 1) returns 18

On the other hand, the SPREAD OPERATOR (…) is used with arrays, object expressions, and function calls, and can spread out the values from these structures into separate arguments. This enables easy merging of arrays and objects, writing functions that accept multiple arguments easily, and copying arrays and other iterable objects.

For example:

function mergeArrays(arr1, arr2){
  return [...arr1, ...arr2];
mergeArrays([1,2], [3,4]); // returns [1, 2, 3, 4]

const obj1 = {a: 1, b: 2, c: 3};
const obj2 = {d: 4, e: 5};
const mergedObj = {...obj1, ...obj2}; 
// mergedObj will be {a: 1, b: 2, c: 3, d: 4, e: 5}

In conclusion, the rest parameter and spread operator are powerful features in Javascript that allow us to work with arrays, objects, and function parameters more easily and efficiently.Using Promises in JavaScript: A brief overview


Promises are a way to handle asynchronous operations in JavaScript. Before promises, callbacks were used which made the code hard to manage. Promise object has four states:

* Pending - Initial state of promise. * Fulfilled - This state represents that the promise has been fulfilled, meaning the async operation is completed. * Rejected - This state represents that the promise has been rejected for some reason, meaning the async operation has failed. * Settled - This state represents that the promise has been either rejected or fulfilled.

A promise is created using the `Promise` constructor which takes in a callback function with two parameters, `resolve` and `reject` respectively. `resolve` is a function that will be called when the async operation has been successfully completed. `reject` is a function that will be called when the async operation fails or if some error occurs.

Example: In the code below, we are returning a promise inside a function.

function sumOfThreeElements(...numbers) {
  return new Promise((resolve, reject) => {
    if (numbers.length > 3 ) {
      reject("Only three elements or less are allowed");
    } else {
      let sum = 0;
      let i = 0;
      while (i < numbers.length) {
        sum += numbers[i];

For the ease of understanding, we are using an operation to calculate the sum of three elements. In the function above, a new promise is created and returned. The function takes in an array of numbers and checks if there are more than three elements present in the array, then it will reject with an error message. If there are three or fewer elements, then it will calculate the sum of the given elements and resolve the promise with the result.

To use the above `sumOfThreeElements` function, we can call the function like this:

.then(result => console.log(result))
.catch(error => console.log(error));

In the code above, the promise is fulfilled so the `then()` method gets executed. It logs the result i.e the sum of the given elements. If the promise is rejected, then the `catch()` method gets executed and it will log the error message.

Introduction to Classes in JavaScript

Classes in JavaScript are a new way to declare constructor functions and were introduced in the ES6 version. They provide a simpler syntax for creating objects. Here is an example of how classes are declared and used:

// Before ES6 version, using constructor functions
function Student(name, rollNumber, grade, section){
  this.name = name;
  this.rollNumber = rollNumber;
  this.grade = grade;
  this.section = section;

// Way to add methods to a constructor function
Student.prototype.getDetails = function(){
  return 'Name: ${this.name}, Roll no: ${this.rollNumber}, Grade: ${this.grade}, Section: ${this.section}';

let student1 = new Student("John", 354, "6th", "A");
// Returns Name: John, Roll no: 354, Grade: 6th, Section: A

//ES6 version classes
class Student{
    this.name = name;
    this.rollNumber = rollNumber;
    this.grade = grade;
    this.section = section;

  // Methods can be directly added inside the class
    return `Name: ${this.name}, Roll no: ${this.rollNumber}, Grade:${this.grade}, Section:${this.section}`;

let student2 = new Student("Garry", 673, "7th", "C");
//Returns Name: Garry, Roll no: 673, Grade: 7th, Section: C

Key Points to Remember about Classes in JavaScript

  • Unlike functions, classes are not hoisted. A class cannot be used before it is declared.
  • A class can inherit properties and methods from other classes by using the "extends" keyword.
  • All the syntaxes inside the class must follow the "strict mode" ("use strict") of JavaScript. An error will be thrown if the strict mode rules are not followed.

Generator Functions in JavaScript

Generator functions are a special type of function introduced in the ES6 version of JavaScript. They are declared using the `function*` keyword instead of the usual `function` keyword. A generator function can be stopped midway and then continue from where it had stopped, making them highly flexible and ideal for handling complex operations.

In traditional functions, the `return` keyword is used to return a value, and when executed, the function stops immediately. However, in generator functions, when called, they do not execute the code but instead return a generator object that handles the execution.

The generator object consists of a method called `next()`, which executes the code until the nearest `yield` statement and returns the yielded value. The `next()` method returns an object that has the `value` and `done` properties. The `value` property represents the yielded value, and the `done` property indicates whether the function code has finished or not.

Generator functions are typically used to return iterators, which can be used to perform certain operations. For instance, we can define an iterator function as follows:

function* iteratorFunc() {
  let count = 0;
  for (let i = 0; i < 5; i++) {
    yield count += i;

In the above code, the `count` variable is initialized to 0, and the function returns the iterator object. When we call the `next()` method on this iterator object, the generator function runs until it reaches the first `yield` statement and returns the appropriate value. Subsequent calls to `next()` return subsequent yielded values until it reaches the end of the iterator function.

Generator functions offer a powerful mechanism for handling complex operations in JavaScript and provide much-needed flexibility in a wide range of applications.

WeakSet in Javascript

In Javascript, a Set is a collection of unique and ordered elements. However, a WeakSet also exists with some key differences:

* A WeakSet can only contain objects; it cannot contain any other data types. * Objects contained within a WeakSet are referenced weakly. This means that if an object within a WeakSet has no other references, it will be garbage collected and removed from the set. * Unlike a Set, a WeakSet has only three methods: ADD(), DELETE(), and HAS().

Here's an example of using a WeakSet in Javascript:

let set = new WeakSet();
let obj1 = {message: "Hello, world!"};
let obj2 = {message: "Goodbye, world!"};


console.log(set.has(obj1)); // true
console.log(set.has(obj2)); // true


console.log(set.has(obj1)); // false

In this example, we create a new WeakSet, add two objects to it, and then check if those objects are contained within the set using the HAS() method. We then remove obj1 from the set using the DELETE() method, and check to see if it is still contained within the set (which returns false).

Explanation of WeakMap in JavaScript

In JavaScript,


is a useful data structure that allows you to store key-value pairs of both primitive and non-primitive data types. However, there is another data structure called


that is similar to


, but with some key differences.

One of the main differences between




is that the keys and values stored in a


must always be an object. Attempting to use a non-object as a key or value will result in an error.

The other major difference is that objects stored in a


are held weakly, which means that if there are no other references to an object in a


, the object will be garbage collected. This behavior can be useful for managing memory in certain situations.

Here is an example of using


in JavaScript:

let obj = { name: "John" };
const map = new WeakMap();
map.set(obj, { age: 23 });

In this example, we create a new


and add an object as the key and another object as the value. Because there are no other references to the key object, it will be garbage collected if it goes out of scope.



can be a useful tool for managing memory and objects in certain situations, but its use cases may be limited compared to



What is Object Destructuring?

Object destructuring is a way to extract elements from an object or an array in JavaScript. Prior to ES6, it was done by individually assigning each property a variable. With object destructuring, you can extract all the elements in one line of code using curly braces.

Object Destructuring
Let's take a look at how we can use object destructuring in the following example where we defined a class object:

const classDetails = {
    strength: 78,
    benches: 39,

Instead of accessing each element of the object as we did in the earlier versions, we can use object destructuring to extract all the variables at once:

const {strength:classStrength, benches:classBenches, blackBoard:classBlackBoard} = classDetails;

console.log(classStrength); // Outputs 78
console.log(classBenches); // Outputs 39
console.log(classBlackBoard); // Outputs 1

By using object destructuring, we are extracting values of properties from the object classDetails and storing them in separate variables classStrength, classBenches, and classBlackBoard respectively.

If we want our new variable to have the same name as the property of an object, we can directly assign the variable a property name like this:

const {strength} = classDetails;

For array destructuring, we can do the following:

Array Destructuring:
Prior to ES6, we used to extract array elements by individually assigning each value to a variable. With ES6, it has become easier. For example,

const arr = [1, 2, 3, 4];

Instead of accessing each value of the array, we can use array destructuring to extract all the elements in one line of code:

const [first,second,third,fourth] = arr;

console.log(first); // Outputs 1
console.log(second); // Outputs 2
console.log(third); // Outputs 3
console.log(fourth); // Outputs 4

By using array destructuring, we are extracting each value of an array and storing them in separate variables - first, second, third, and fourth.

What is Temporal Dead Zone?

Temporal Dead Zone is a behavior that occurs when variables are declared using the LET and CONST keywords. It is the behavior of trying to access a variable before it is initialized. Below are examples of the temporal dead zone:

let x;
x = 23; // Gave reference error

function anotherRandomFunction() {
   let message;
   message = "Hello"; // Throws a reference error

In the code above, we are trying to access variables that have not yet been declared both in the global scope and functional scope. This occurrence is called Temporal Dead Zone.

Guess the Outputs of the Following JavaScript Codes

// Code 1:

The output of Code 1 is 2 and 12. This is because the function runs first and sets the variable x to 2 and the let variable y as 12. Even though let variables are not hoisted, the setTimeout function has access to x and y before it executes.

// Code 2:

The output of Code 2 is 3 logged three times. The reason for this is that the variable i is declared with var, which doesn't have block scope. Additionally, in the for loop, i is incremented before it is checked, which causes the loop to run three times.

// Code 3:

The output of Code 3 is as follows:

  • 2
  • 4
  • 3
  • 1 (after two seconds)

This is because even though the second setTimeout function has a waiting time of 0 seconds, the JavaScript engine evaluates the setTimeout function using the Web API. Therefore, the complete function executes first, and then the setTimeout function can execute.

Guess the outputs of the following code:

  // Code 1:

  let x = {};
  let y = {name: "Ronny"};
  let z = {name: "John"};

  x[y] = {name: "John"};
  x[z] = {name: "Akki"};

  console.log(x[y]); // Output: {name: "Akki"}

  // Code 2:

  function runFunc() {
    console.log("1" + 1); // Output: "11"
    console.log("A" - 1); // Output: NaN
    console.log(2 + "-2" + "2"); // Output: "2-22"
    console.log("Hello" - "World" + 78); // Output: NaN
    console.log("Hello" + "78"); // Output: "Hello78"


  // Code 3:

  let a = 0;
  let b = false;

  console.log((a == b)); // Output: true
  console.log((a === b)); // Output: false


  • Code 1:
    • When you add an object as a property of another object, JavaScript coerces the parameter into a string. So, both x[y] and x[z] are referencing the same property. In this case, the final value that was assigned to x[y] was {name: "John"}, but since both x[y] and x[z] are pointing to the same reference, the output of console.log(x[y]) will be {name: "Akki"}.
  • Code 2:
    • When you use the plus operator (+) between a string and a number, JavaScript will implicitly convert the number to a string and concatenate both values. For example, "1" + 1 will output "11".
    • When you use the minus operator (-) between a string and a number, JavaScript will try to convert the string to a number. If the string doesn't represent a valid number, the result will be NaN (Not a Number).
  • Code 3:
    • When you use the double equal (==) operator, JavaScript will try to coerce the values to the same type before making the comparison. In this case, 0 and false are both considered falsy values, so a == b will output true.
    • When you use the triple equal (===) operator, JavaScript won't try to coerce the values and will only compare if they are of the same type and have the same value. In this case, 0 is a number and false is a boolean, so a === b will output false.

Guess the Output of the Following Code:

var x = 23;

(function() {
  var x = 43;

  (function random() {
    var x; // x is hoisted
    x++;  // x is not a number since it is not initialized yet
    console.log(x); // Outputs NaN
    x = 21; // Initialization of x

The output of the code will be NaN. The random() function has functional scope and since x is declared and hoisted in the functional scope, it is not initialized yet. Therefore, x is not a number and the output is NaN.

Guess the Outputs of the Following Code:

// Code 1
let hero = {
  powerLevel: 99,
  getPower() {
    return this.powerLevel;

let getPower = hero.getPower;

let hero2 = {
  powerLevel: 42


// Code 2
const a = function() {

  const b = {
    func1: function() {

  const c = {
    func2: () => {



// Code 3
const b = {
  name: "John",
  f: function() {
    var self = this;
    (function() {


Code 1 - Output in the following order:


Reason - The first output is undefined since when the function is invoked, it is invoked referencing the global object:

window.getPower() = getPower();

Code 2 - Outputs in the following order:

global/window object
object "b"
global/window object

Since we are using an arrow function inside FUNC2, the THIS keyword refers to the global object.

Code 3 - Outputs in the following order:


Only in the IIFE (Immediately Invoked Function Expression) inside the function F, the THIS keyword refers to the global/window object.

Guess the Outputs of the Following Code:

// Code 1

  return (function(){
    num = 23;

// Code 2

// Create the array only once using closures
function createBigArray(element){
  let arr = new Array(700).fill('♥');
  return function() {
     return arr[element];

let getArrayElement = createBigArray(599);
getArrayElement = createBigArray(670);

// Code 3

// Modify the code to output 0 and 1 after one second.
function printNum(){
  for(let i = 0; i < 2; i++){
    setTimeout(() => console.log(i), 1000 * i);


Code 1 - Outputs 45. Even though "num" is defined in the outer function, due to closure the inner function has access to it.

Code 2 - The code is modified using closures. The array is created only once and then returned, so it can be used to get any element from the array whenever needed.

Code 3 - The code is modified to use the LET keyword to declare the variable "i" in the for loop. Alternatively, closures can be used to capture the value of i during each iteration.

Function to Perform Binary Search on a Sorted Array

function binarySearch(sortedArray, desiredValue, startIndex, endIndex) {
  if(startIndex > endIndex) return -1;

  let middleIndex = Math.floor((startIndex + endIndex) / 2);
  if(sortedArray[middleIndex] === desiredValue) return middleIndex;

  if(sortedArray[middleIndex] > desiredValue) {
    return binarySearch(sortedArray, desiredValue, startIndex, middleIndex - 1);
  else {
    return binarySearch(sortedArray, desiredValue, middleIndex + 1, endIndex);

The above code is a function in JavaScript that performs a binary search on a sorted array. The function takes in four parameters: the sorted array itself, the desired value to search for, the starting index, and the ending index. The function uses recursion to perform the binary search and returns the index of the desired value if it exists in the array. If the value is not found, the function returns -1.


Function to rotate an array of integers to the right by a given number of rotations

This function takes an array of integers A and a number R as input and returns an updated array with R right rotations. The function works by taking the last element of the array and moving it to the beginning R times.

function rotateArrayRight(A, R) {
    if (R === 0) return A;
    const len = A.length;
    const rotations = R % len;
    for (let i = 0; i < rotations; i++) {
        let temp = A[len - 1];
        for (let j = len - 1; j > 0; j--) {
            A[j] = A[j - 1];
        A[0] = temp;
    return A;

To use this function, call it and pass in an array of integers A and the number of rotations R:

let A = [2, 3, 4, 5, 7];
let R = 3;
let rotatedArray = rotateArrayRight(A, R);
console.log(rotatedArray); // will output [4, 5, 7, 2, 3]

Technical Interview Guides

Here are guides for technical interviews, categorized from introductory to advanced levels.

View All

Best MCQ

As part of their written examination, numerous tech companies necessitate candidates to complete multiple-choice questions (MCQs) assessing their technical aptitude.

View MCQ's
Made with love
This website uses cookies to make IQCode work for you. By using this site, you agree to our cookie policy

Welcome Back!

Sign up to unlock all of IQCode features:
  • Test your skills and track progress
  • Engage in comprehensive interactive courses
  • Commit to daily skill-enhancing challenges
  • Solve practical, real-world issues
  • Share your insights and learnings
Create an account
Sign in
Recover lost password
Or log in with

Create a Free Account

Sign up to unlock all of IQCode features:
  • Test your skills and track progress
  • Engage in comprehensive interactive courses
  • Commit to daily skill-enhancing challenges
  • Solve practical, real-world issues
  • Share your insights and learnings
Create an account
Sign up
Or sign up with
By signing up, you agree to the Terms and Conditions and Privacy Policy. You also agree to receive product-related marketing emails from IQCode, which you can unsubscribe from at any time.