This is a Question Bank, not a Study Material.

Other materials to consider

HTML interview questions

CSS interview questions

React Interview questions

Angular Interview Questions

Core Concepts

1. Event Loop

The event loop is a critical concept in JavaScript, especially in the context of asynchronous programming. It is what allows JavaScript to handle tasks like responding to user interactions, making network requests, and executing code efficiently without blocking the main thread. Here's an explanation of the event loop in JavaScript:

  1. JavaScript is Single-Threaded: JavaScript is single-threaded, meaning it can only execute one operation at a time in a single main thread. This single-threaded nature can lead to problems if tasks take too long to complete, as it can make a web page unresponsive.

  2. The Callback Queue: When asynchronous operations complete, their corresponding callbacks are placed in the callback queue. This includes things like timer callbacks, user interactions, and network responses.

  3. Asynchronous Programming: To handle time-consuming tasks without blocking the main thread, JavaScript uses asynchronous programming. This involves callbacks, promises, and more recently, async/await.

  4. The Call Stack: JavaScript has a call stack that keeps track of the functions currently being executed. When a function is called, it's pushed onto the stack. When a function returns, it's popped from the stack. The call stack processes functions in a last-in, first-out (LIFO) manner.

  5. Concurrency Model: JavaScript's concurrency model is based on the event loop. It allows JavaScript to efficiently manage multiple tasks and events without blocking the main thread. This is crucial for building responsive web applications.

  6. The Event Loop:

The event loop is a mechanism that continuously checks both the call stack and the callback queue. It ensures that when the call stack is empty, it picks the next callback from the queue and pushes it onto the stack for execution.

ev-loop.png

Here's a simplified example of how the event loop works:

In this example,

Understanding the event loop is essential for effective asynchronous programming in JavaScript, especially when dealing with tasks that may take some time to complete, such as fetching data from a server or responding to user interactions.

console.log("Start");

setTimeout(() => {
  console.log("Callback 1");
}, 1000);

setTimeout(() => {
  console.log("Callback 2");
}, 500);

console.log("End");

//Output
Start
End
Callback 2
Callback 1

2. Macro and Micro Tasks

Macro tasks and micro tasks are two categories of tasks in JavaScript's event loop. They are part of the asynchronous execution model and play a crucial role in handling concurrency and asynchronous operations.

Micro Tasks:

Macro Tasks (or Tasks):

<aside> 💡

The difference in priority between macro tasks and micro tasks can lead to specific execution behaviors. When the call stack is empty, the event loop checks and processes micro tasks before macro tasks. This behavior ensures that micro tasks are executed promptly, which is essential for tasks like promise resolution, making it easier to reason about the order of execution in certain asynchronous scenarios.

Here's a simplified flow of how macro and micro tasks are processed:

  1. Execute code in the call stack.
  2. Check for and execute any available micro tasks in the microtask queue.
  3. Check for and execute any available macro tasks in the task queue.
  4. Repeat steps 2 and 3 as long as there are tasks to process. </aside>

3. What is hoisting?

Hoisting is a behavior in JavaScript where variable and function declarations are moved to the top of their containing scope during the compilation phase, before the code is executed. This means that you can use variables and functions in your code before they are declared in the source code, which might seem counterintuitive but is important to understand.

There are two main aspects of hoisting in JavaScript:

  1. Variable Hoisting: When you declare a variable using var, it is hoisted to the top of its containing function or global scope. However, only the declaration is hoisted, not the initialization. This means that the variable is accessible before its declaration in code but will have an initial value of undefined.

    In the code above, x is hoisted to the top of the scope, so the console.log(x) statement doesn't throw an error. Still, x is undefined until it's assigned the value 10 later in the code.

    It's important to note that the behavior of let and const is different. Variables declared with let and const are also hoisted to the top of their scope, but they are not initialized until the actual declaration in the code. This is known as the "temporal dead zone," and trying to access such variables before declaration results in a ReferenceError.

console.log(x); // undefined
var x = 10;
  1. Function Hoisting: Function declarations are also hoisted to the top of their containing scope, including their entire definition, not just the name.

    In the code above, the greet() function is called before its declaration, but it works as expected because the entire function, including its definition, is hoisted to the top.

greet(); // "Hello, world!"

function greet() {
  console.log("Hello, world!");
}

<aside> 💡 class, let and const are non hoisting

</aside>

4. Explain the this keyword in JS

In JavaScript, the this keyword is a special identifier that refers to the current execution context or the object that a function is operating on. The purpose of the this keyword is to provide a way for functions to access and manipulate data associated with the current context, which can vary depending on how the function is called or where it is defined. The specific behavior of this can be a source of confusion for many developers, as it can change in different situations.

Here are some common scenarios where the this keyword is used and its purpose: