Top 10 JavaScript Interview Questions with Answers (2025)

Rishabh MishraRishabh Mishra
7 min read

JavaScript is one of the most in-demand programming languages in 2025. Whether you're a fresher or an experienced developer, these interview questions can help you ace your next interview.

1. What is the difference between var, let, and const?

  • var: This keyword is function-scoped, meaning that variables declared with var are accessible within the function they are defined in. Variables declared with var can also be re-declared within the same scope, which means you can define a variable with the same name multiple times without causing an error.

  • let: This keyword is block-scoped, which means variables declared with let are only accessible within the block (enclosed by curly braces {}) where they are defined. Unlike var, variables declared with let cannot be re-declared within the same block, which helps prevent accidental overwriting of variables.

  • const: Similar to let, the const keyword is block-scoped, so variables declared with const are only accessible within the block where they are defined. However, const has an additional restriction: once a variable is declared with const, it cannot be re-declared or reassigned a new value. This makes const ideal for defining variables that should remain constant throughout the execution of a program.

var a = 10;
let b = 20;
const c = 30;

a = 15; // valid
b = 25; // valid
c = 35; // ❌ Error

2. What is a closure in JavaScript?

A closure in JavaScript is a feature where a function retains access to variables from its surrounding lexical environment, even after the outer function has completed its execution. This means that the inner function can continue to access and manipulate those variables, preserving their state. Closures are often used to create private variables or functions, and they enable powerful patterns like function factories and encapsulation.

function outer() {
  let count = 0;
  return function inner() {
    count++;
    console.log(count);
  }
}

const counter = outer();
counter(); // 1
counter(); // 2

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 compile phase, before the code is executed. This means that you can use variables and functions before they are declared in the code. However, only the declarations are hoisted, not the initializations. For variables declared with var, the variable is hoisted and initialized with undefined. For let and const, the declarations are hoisted, but they are not initialized, leading to a "temporal dead zone" until the line of code where they are initialized is reached.

console.log(x); // undefined
var x = 5;

Variables declared with var are hoisted and initialized with undefined.
let and const are hoisted but not initialized.


4. Explain the this keyword in JavaScript.

The this keyword in JavaScript is a reference to the object that is currently executing the function. Its value depends on how the function is called. In a method, this refers to the owner object. In a regular function, this refers to the global object (or undefined in strict mode). In an event, this refers to the element that received the event. Additionally, this can be explicitly set using methods like call(), apply(), or bind().

const obj = {
  name: "Rishabh",
  getName: function () {
    return this.name;
  }
};

console.log(obj.getName()); // Rishabh

In arrow functions, this refers to the parent lexical context.


5. Difference between == and ===

  • == performs type conversion before comparing values, which means it checks if the values are equal after converting them to a common type (loose equality).

  • === checks both the value and the type without performing any type conversion, ensuring that both must be exactly the same (strict equality).

5 == "5"; // true
5 === "5"; // false

6. What are arrow functions?

Arrow functions provide a concise syntax for writing functions in JavaScript. They are defined using the => syntax, which makes them shorter and often easier to read compared to traditional function expressions. One key characteristic of arrow functions is that they do not have their own this context. Instead, they inherit this from the surrounding lexical scope at the time they are defined. This behavior makes arrow functions particularly useful in situations where you want to preserve the this value from the outer context, such as in callbacks or when working with methods inside classes.

const add = (a, b) => a + b;

They’re best for short, anonymous functions.


7. What is event bubbling and delegation?

  • Event Bubbling: This is a process where events start from the deepest target element and then move up to the parent elements in the Document Object Model (DOM). It means that when an event occurs on an element, it first runs the handlers on that element, then on its parent, and so on, moving up the hierarchy.

  • Event Delegation: This technique involves attaching a single event handler to a parent element to manage events for multiple child elements. Instead of adding individual event listeners to each child element, you add one listener to a common ancestor. This approach takes advantage of event bubbling, allowing the event to be captured at a higher level in the DOM.

document.getElementById("parent").addEventListener("click", function(e) {
  if (e.target.tagName === "BUTTON") {
    console.log("Button clicked:", e.target.textContent);
  }
});

8. What are Promises and async/await?

  • Promise: A Promise is an object that represents the eventual completion or failure of an asynchronous operation. It allows you to attach callbacks to handle the result or error once the operation is completed. Promises are used to manage asynchronous tasks in a more organized way, avoiding the complexities of callback functions.

  • async/await: async/await is a syntactic feature in JavaScript that simplifies working with Promises. It allows you to write asynchronous code that looks and behaves like synchronous code, making it easier to read and maintain. By using async before a function, you can use await inside that function to pause execution until a Promise is resolved or rejected, thus handling asynchronous operations more intuitively.

async function fetchData() {
  try {
    const res = await fetch("https://api.example.com");
    const data = await res.json();
    console.log(data);
  } catch (error) {
    console.error(error);
  }
}

9. What is a callback function?

A callback function is a function that you pass as an argument to another function. This function is then executed at a later time, usually after some kind of event or operation has completed. Callback functions are often used in asynchronous programming to ensure that a certain piece of code runs only after a specific task is finished. For example, in JavaScript, you might use a callback function to handle the result of an API call or to execute code after a timeout. Here's a simple example:

function fetchData(url, callback) {
  // Simulate an API call
  setTimeout(() => {
    const data = { name: "John", age: 30 };
    callback(data);
  }, 1000);
}

function handleData(data) {
  console.log("Data received:", data);
}

fetchData("https://api.example.com", handleData);

In this example, fetchData takes a URL and a callback function handleData. After simulating a delay with setTimeout, it calls handleData with the data, allowing handleData to process the data once it's available.

function greet(name, callback) {
  console.log("Hi " + name);
  callback();
}

greet("Rishabh", () => {
  console.log("Welcome to DevDaily!");
});

10. What is setTimeout and setInterval?

  • setTimeout: This function is used to execute a specific function once after a specified delay. The delay is defined in milliseconds, and the function will run only one time after this delay has passed.

  • setInterval: This function is used to execute a specific function repeatedly at regular intervals. The interval is defined in milliseconds, and the function will continue to run at these intervals until it is stopped.

  •   setTimeout(() => {
        console.log("Runs once after 2 seconds");
      }, 2000);
    
      setInterval(() => {
        console.log("Runs every 3 seconds");
      }, 3000);
    

These questions are frequently asked in JavaScript interviews and help interviewers test your understanding of core concepts. Make sure to understand the logic, not just memorize the answers.

👉 Found this helpful? Follow DevDaily for more developer blogs every week!

✍ Written by Rishabh Mishra

1
Subscribe to my newsletter

Read articles from Rishabh Mishra directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Rishabh Mishra
Rishabh Mishra

Hey, I’m Rishabh — a developer who writes code like poetry and breaks things just to rebuild them better. .NET Full Stack Dev | Razor, C#, MVC, SQL, Angular — my daily playground. I believe in “learning out loud” — so I write about dev struggles, breakthroughs, and the weird bugs that teach the best lessons. From building ERP apps to tinkering with UI/UX — I turn business logic into beautiful experiences. Self-growth > Comfort zone | Debugging is my meditation Let’s turn curiosity into code — one blog at a time.