JavaScript remains one of the most in-demand programming languages in the tech industry. Whether you’re preparing for your first interview or advancing to a senior role, mastering core JavaScript concepts is essential. This comprehensive guide covers 30 interview questions ranging from basic to advanced levels, designed to help candidates at all experience levels succeed in technical interviews.
Basic JavaScript Interview Questions
1. What are the different data types in JavaScript?
JavaScript has two main categories of data types: primitive and object types.
Primitive data types include:
- String: Text values enclosed in quotes
- Number: Integer and floating-point numbers
- Boolean: true or false values
- Null: Intentional absence of value
- Undefined: Variables declared but not assigned
- Symbol: Unique identifiers (ES6+)
- BigInt: Large integers beyond Number limits (ES2020)
Object data types include:
- Object: Collections of key-value pairs
- Array: Ordered collections of values
- Function: Reusable blocks of code
2. What is the difference between == and === in JavaScript?
The == operator performs loose equality comparison and converts operands to the same type before comparing. The === operator performs strict equality comparison without type conversion.
console.log(5 == "5"); // true (loose equality, type coercion)
console.log(5 === "5"); // false (strict equality, different types)
console.log(0 == false); // true (loose equality)
console.log(0 === false); // false (strict equality)
Best practice is to use === to avoid unexpected type coercion issues.
3. What is hoisting in JavaScript?
Hoisting is JavaScript’s behavior of moving declarations to the top of their scope during the compilation phase, before code execution. This applies to variable declarations with var, let, const, and function declarations.
console.log(x); // undefined (not an error)
var x = 5;
sayHello(); // "Hello World" (function works before declaration)
function sayHello() {
console.log("Hello World");
}
console.log(y); // ReferenceError
let y = 10;
Variables declared with var are hoisted and initialized as undefined. Variables with let and const are hoisted but not initialized, remaining in the temporal dead zone until the declaration is reached.
4. What is the difference between let, const, and var?
These three keywords define variables with different scoping and reassignment behaviors:
// var: function scope, can be reassigned and re-declared
var a = 10;
var a = 20; // allowed
a = 30; // allowed
console.log(a); // 30
// let: block scope, can be reassigned but not re-declared
let b = 10;
let b = 20; // Error
b = 30; // allowed
console.log(b); // 30
// const: block scope, cannot be reassigned or re-declared
const c = 10;
const c = 20; // Error
c = 30; // Error
console.log(c); // 10
Modern JavaScript best practices recommend using const by default, let when reassignment is needed, and avoiding var.
5. What is the temporal dead zone (TDZ)?
The temporal dead zone is the period between entering a scope and reaching the declaration of a let or const variable. During this time, accessing the variable throws a ReferenceError.
console.log(x); // ReferenceError: Cannot access 'x' before initialization
let x = 5;
This differs from var, which is hoisted and initialized as undefined, making it accessible (with an undefined value) before its declaration line.
6. What is truthy and falsy in JavaScript?
In JavaScript, values are evaluated as either truthy or falsy when used in boolean contexts.
Falsy values are:
- false (boolean)
- 0 (number)
- -0 (negative zero)
- 0n (BigInt zero)
- “” (empty string)
- null
- undefined
- NaN (Not a Number)
All other values are truthy, including non-zero numbers, non-empty strings, objects, arrays, and functions.
if (0) {
console.log("Won't execute");
}
if (1) {
console.log("Will execute"); // Output: Will execute
}
if ("") {
console.log("Won't execute");
}
if ("hello") {
console.log("Will execute"); // Output: Will execute
}
7. What does the ‘this’ keyword refer to in JavaScript?
The this keyword refers to the object that is currently executing the code. Its value depends on how a function is called.
// Global context
console.log(this); // window object (in browsers)
// Inside an object method
const person = {
name: "John",
greet: function() {
console.log(this.name); // "John"
}
};
person.greet();
// Regular function
function test() {
console.log(this); // window object (in browsers)
}
test();
// Arrow function inherits 'this' from parent scope
const obj = {
name: "Jane",
regular: function() {
console.log(this.name); // "Jane"
},
arrow: () => {
console.log(this.name); // undefined
}
};
8. Explain null and undefined in JavaScript.
null is an intentional assignment representing “no value” or “empty value.” undefined is the default value for uninitialized variables or functions without a return statement.
let x = null; // Intentional absence of value
let y; // undefined (not assigned)
let z = undefined; // Explicit assignment of undefined
console.log(typeof null); // "object" (quirk of JavaScript)
console.log(typeof undefined); // "undefined"
console.log(null == undefined); // true (loose equality)
console.log(null === undefined); // false (strict equality)
9. What is variable shadowing in JavaScript?
Variable shadowing occurs when a variable declared in an inner scope has the same name as a variable in an outer scope, effectively hiding or “shadowing” the outer variable within that inner scope.
let x = "global";
function outer() {
let x = "outer";
function inner() {
let x = "inner";
console.log(x); // "inner"
}
inner();
console.log(x); // "outer"
}
outer();
console.log(x); // "global"
Shadowing can make code harder to understand and is generally considered poor practice. Using a linter can help identify and prevent variable shadowing issues.
10. What is strict mode in JavaScript?
Strict mode is an opt-in feature that enforces stricter parsing and error handling in JavaScript code. It prevents certain unsafe actions and throws errors for common coding mistakes.
"use strict";
x = 5; // Error: x is not defined (must declare variables)
function test() {
console.log(this); // undefined (not window)
}
test();
const obj = {};
Object.defineProperty(obj, "prop", { value: 42, writable: false });
obj.prop = 100; // Error: Cannot assign to read-only property
Strict mode can be applied globally at the top of a file or within individual functions. It’s highly recommended for modern JavaScript development.
Intermediate JavaScript Interview Questions
11. What is a closure in JavaScript?
A closure is a function that has access to variables from its own scope, the outer function’s scope, and the global scope, even after the outer function has returned. Closures are created every time a function is created.
function outer(x) {
function inner(y) {
return x + y; // inner accesses x from outer
}
return inner;
}
const add5 = outer(5);
console.log(add5(3)); // 8
const add10 = outer(10);
console.log(add10(3)); // 13
Closures are powerful for data privacy, function factories, and implementing the module pattern. They’re commonly used in callbacks and higher-order functions.
12. How do you create an object in JavaScript?
There are several ways to create objects in JavaScript:
// 1. Object literal
const person1 = {
name: "Alice",
age: 30,
greet: function() {
console.log("Hello");
}
};
// 2. Constructor function
function Person(name, age) {
this.name = name;
this.age = age;
}
const person2 = new Person("Bob", 25);
// 3. Object.create() method
const personProto = {
greet() {
console.log(`Hello, I'm ${this.name}`);
}
};
const person3 = Object.create(personProto);
person3.name = "Charlie";
person3.greet();
// 4. ES6 Class syntax
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log(`Hi, I'm ${this.name}`);
}
}
const person4 = new Person("Diana", 28);
// 5. Object constructor
const person5 = new Object();
person5.name = "Eve";
person5.age = 32;
13. How do you add or remove properties from an object dynamically?
Properties can be added or removed from objects at runtime using dot notation, bracket notation, or the delete operator.
const user = { name: "John" };
// Add properties
user.age = 30; // Dot notation
user["email"] = "john@example.com"; // Bracket notation
Object.assign(user, { city: "New York" });
console.log(user);
// { name: "John", age: 30, email: "john@example.com", city: "New York" }
// Remove properties
delete user.age;
console.log(user);
// { name: "John", email: "john@example.com", city: "New York" }
14. What is the difference between for…in and for…of loops?
for…in iterates over enumerable property names (keys) of an object, while for…of iterates over the values of iterable objects like arrays and strings.
const arr = [10, 20, 30];
const obj = { a: 1, b: 2, c: 3 };
// for...in iterates over indices/keys
for (let i in arr) {
console.log(i); // 0, 1, 2 (strings)
}
// for...of iterates over values
for (let val of arr) {
console.log(val); // 10, 20, 30
}
// for...in with objects
for (let key in obj) {
console.log(key); // a, b, c
}
// for...of doesn't work directly with objects
// for (let val of obj) { // Error
// }
15. What is the purpose of the map() function?
The map() function creates a new array by applying a function to each element of the original array, transforming each element without modifying the original array.
const numbers = [1, 2, 3, 4, 5];
// Double each number
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
// Extract object properties
const users = [
{ name: "Alice", age: 25 },
{ name: "Bob", age: 30 }
];
const names = users.map(user => user.name);
console.log(names); // ["Alice", "Bob"]
// Convert strings to numbers
const strings = ["1", "2", "3"];
const nums = strings.map(Number);
console.log(nums); // [1, 2, 3]
16. Explain the difference between filter() and find() methods.
filter() returns a new array containing all elements that match a condition, while find() returns only the first element that matches the condition (or undefined if none match).
const numbers = [10, 20, 30, 40, 50];
// filter() returns all matching elements
const greaterThan25 = numbers.filter(num => num > 25);
console.log(greaterThan25); // [30, 40, 50]
// find() returns first matching element
const firstGreaterThan25 = numbers.find(num => num > 25);
console.log(firstGreaterThan25); // 30
const users = [
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" },
{ id: 3, name: "Charlie" }
];
// filter() gets multiple results
const multipleUsers = users.filter(user => user.id > 1);
console.log(multipleUsers);
// [{ id: 2, name: "Bob" }, { id: 3, name: "Charlie" }]
// find() gets single result
const singleUser = users.find(user => user.id === 2);
console.log(singleUser); // { id: 2, name: "Bob" }
17. What is the difference between some() and every() methods?
some() returns true if at least one element matches the condition, while every() returns true only if all elements match the condition.
const scores = [45, 60, 75, 80];
// some() checks if at least one element meets condition
const hasPass = scores.some(score => score >= 50);
console.log(hasPass); // true
// every() checks if all elements meet condition
const allPass = scores.every(score => score >= 50);
console.log(allPass); // false
const products = [
{ name: "Laptop", inStock: true },
{ name: "Phone", inStock: true },
{ name: "Tablet", inStock: false }
];
// some() - at least one in stock
const anyAvailable = products.some(p => p.inStock);
console.log(anyAvailable); // true
// every() - all in stock
const allAvailable = products.every(p => p.inStock);
console.log(allAvailable); // false
18. What is a callback function?
A callback function is a function passed as an argument to another function, which is then invoked inside the outer function. Callbacks are fundamental to asynchronous JavaScript programming.
// Simple callback example
function greet(name, callback) {
console.log("Hello " + name);
callback();
}
function sayGoodbye() {
console.log("Goodbye");
}
greet("John", sayGoodbye);
// Output: Hello John
// Goodbye
// Array method callbacks
const numbers = [1, 2, 3];
numbers.forEach(function(num) {
console.log(num * 2); // 2, 4, 6
});
// setTimeout callback
setTimeout(function() {
console.log("Executed after 2 seconds");
}, 2000);
19. What is callback hell and how do you avoid it?
Callback hell (also called pyramid of doom) occurs when multiple nested callbacks make code difficult to read and maintain. This happens frequently in asynchronous operations.
// Callback hell
getUser(userId, function(user) {
getOrders(user.id, function(orders) {
getOrderDetails(orders[0].id, function(details) {
processPayment(details, function(result) {
console.log(result);
});
});
});
});
// Solution 1: Named functions
function handleUser(user) {
getOrders(user.id, handleOrders);
}
function handleOrders(orders) {
getOrderDetails(orders[0].id, handleDetails);
}
function handleDetails(details) {
processPayment(details, handlePayment);
}
function handlePayment(result) {
console.log(result);
}
getUser(userId, handleUser);
// Solution 2: Promises
getUser(userId)
.then(user => getOrders(user.id))
.then(orders => getOrderDetails(orders[0].id))
.then(details => processPayment(details))
.then(result => console.log(result));
// Solution 3: Async/await
async function processUserOrder() {
const user = await getUser(userId);
const orders = await getOrders(user.id);
const details = await getOrderDetails(orders[0].id);
const result = await processPayment(details);
console.log(result);
}
20. What is a Promise in JavaScript?
A Promise is an object representing the eventual completion (or failure) of an asynchronous operation and its resulting value. It has three states: pending, fulfilled (resolved), or rejected.
// Creating a Promise
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
const success = true;
if (success) {
resolve("Operation successful!");
} else {
reject("Operation failed!");
}
}, 2000);
});
// Consuming a Promise
myPromise
.then(result => console.log(result))
.catch(error => console.log(error));
// Promise with real scenario (simulating API call)
function fetchData(url) {
return new Promise((resolve, reject) => {
// Simulating API request
setTimeout(() => {
const data = { id: 1, name: "User" };
resolve(data);
}, 1000);
});
}
fetchData("/api/users/1")
.then(data => console.log(data))
.catch(error => console.log("Error:", error));
21. How do you chain Promises?
Promise chaining allows you to perform sequential asynchronous operations by calling .then() multiple times. Each .then() returns a new Promise, allowing the chain to continue.
fetch("/api/users/1")
.then(response => response.json())
.then(user => {
console.log("User:", user);
return fetch(`/api/posts?userId=${user.id}`);
})
.then(response => response.json())
.then(posts => {
console.log("Posts:", posts);
})
.catch(error => {
console.log("Error:", error);
});
// Promise chain with custom promises
Promise.resolve(5)
.then(num => {
console.log(num); // 5
return num * 2;
})
.then(result => {
console.log(result); // 10
return result + 10;
})
.then(final => {
console.log(final); // 20
});
22. What is Promise.all()?
Promise.all() takes an array of Promises and returns a new Promise that resolves when all input Promises have resolved, or rejects if any Promise rejects.
const promise1 = Promise.resolve(3);
const promise2 = new Promise(resolve => setTimeout(() => resolve("foo"), 100));
const promise3 = fetch("/api/data").then(res => res.json());
Promise.all([promise1, promise2, promise3])
.then(([result1, result2, result3]) => {
console.log("All resolved:", result1, result2, result3);
})
.catch(error => {
console.log("One or more promises rejected:", error);
});
// Practical scenario: Multiple API calls
const fetchUserData = Promise.resolve({ id: 1, name: "John" });
const fetchUserPosts = Promise.resolve([
{ id: 1, title: "First Post" },
{ id: 2, title: "Second Post" }
]);
const fetchUserComments = Promise.resolve([
{ id: 1, text: "Great post!" }
]);
Promise.all([fetchUserData, fetchUserPosts, fetchUserComments])
.then(([userData, posts, comments]) => {
console.log("User profile complete:", {
user: userData,
posts: posts,
comments: comments
});
});
23. What is async/await in JavaScript?
Async/await is syntactic sugar built on top of Promises that makes asynchronous code look and behave more like synchronous code. The async keyword declares an asynchronous function, and await pauses execution until a Promise is resolved.
// Traditional Promise approach
function fetchUser() {
return fetch("/api/users/1")
.then(response => response.json())
.then(user => user);
}
// Async/await approach
async function fetchUserAsync() {
const response = await fetch("/api/users/1");
const user = await response.json();
return user;
}
// Using async/await
async function getUserData() {
try {
const user = await fetch("/api/users/1").then(r => r.json());
console.log("User:", user);
} catch (error) {
console.log("Error:", error);
}
}
getUserData();
// Async/await with multiple operations
async function processOrder(orderId) {
try {
const order = await fetch(`/api/orders/${orderId}`).then(r => r.json());
const payment = await processPayment(order);
const confirmation = await sendConfirmation(payment);
return confirmation;
} catch (error) {
console.log("Order processing failed:", error);
}
}
24. How do you handle errors in async/await?
Errors in async/await can be handled using try…catch blocks, which provide a cleaner syntax than Promise .catch() methods.
// Basic try...catch with async/await
async function fetchData() {
try {
const response = await fetch("/api/invalid-url");
const data = await response.json();
return data;
} catch (error) {
console.log("Error fetching data:", error.message);
} finally {
console.log("Request completed");
}
}
fetchData();
// Handling specific errors
async function processUser(userId) {
try {
const response = await fetch(`/api/users/${userId}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const user = await response.json();
return user;
} catch (error) {
if (error instanceof TypeError) {
console.log("Network error:", error);
} else if (error instanceof SyntaxError) {
console.log("JSON parse error:", error);
} else {
console.log("Unknown error:", error);
}
}
}
// Multiple async operations with error handling
async function getMultipleUsers(userIds) {
try {
const promises = userIds.map(id =>
fetch(`/api/users/${id}`).then(r => r.json())
);
const users = await Promise.all(promises);
return users;
} catch (error) {
console.log("Failed to fetch users:", error);
throw error; // Re-throw to handle at higher level
}
}
Advanced JavaScript Interview Questions
25. What is the difference between async/await and Promises?
While both handle asynchronous operations, async/await provides a cleaner syntax and more intuitive error handling compared to Promises. The key differences include readability, error handling, and debugging capabilities.
// Promise approach
function getData() {
return fetch("/api/data")
.then(response => response.json())
.then(data => {
console.log(data);
return data;
})
.catch(error => console.log("Error:", error));
}
// Async/await approach
async function getDataAsync() {
try {
const response = await fetch("/api/data");
const data = await response.json();
console.log(data);
return data;
} catch (error) {
console.log("Error:", error);
}
}
// Sequential operations
// Promises
function processSequential() {
return fetch("/api/user")
.then(r => r.json())
.then(user => fetch(`/api/posts/${user.id}`))
.then(r => r.json())
.then(posts => console.log(posts));
}
// Async/await (more readable)
async function processSequentialAsync() {
const user = await fetch("/api/user").then(r => r.json());
const posts = await fetch(`/api/posts/${user.id}`).then(r => r.json());
console.log(posts);
}
// Parallel operations
// Promises
function processParallel() {
return Promise.all([
fetch("/api/users").then(r => r.json()),
fetch("/api/posts").then(r => r.json()),
fetch("/api/comments").then(r => r.json())
]).then(([users, posts, comments]) => {
console.log(users, posts, comments);
});
}
// Async/await
async function processParallelAsync() {
const [users, posts, comments] = await Promise.all([
fetch("/api/users").then(r => r.json()),
fetch("/api/posts").then(r => r.json()),
fetch("/api/comments").then(r => r.json())
]);
console.log(users, posts, comments);
}
26. What is the difference between default and named exports?
Default exports allow a module to export a single value as the default, while named exports allow multiple values to be exported with specific names from a single module.
// file: math.js
// Default export
export default function add(a, b) {
return a + b;
}
// file: utils.js
// Named exports
export function multiply(a, b) {
return a * b;
}
export function divide(a, b) {
return a / b;
}
export const PI = 3.14159;
// file: main.js
// Importing default export
import add from "./math.js";
// Importing named exports
import { multiply, divide, PI } from "./utils.js";
// Importing all named exports
import * as utils from "./utils.js";
// Using imports
console.log(add(5, 3)); // 8
console.log(multiply(4, 5)); // 20
console.log(utils.divide(10, 2)); // 5
// Mixing default and named imports
import add, { multiply, divide } from "./modules.js";
27. How do you convert a JavaScript object to a JSON string?
The JSON.stringify() method converts JavaScript objects and values to JSON strings. The reverse operation uses JSON.parse().
const user = {
name: "Alice",
age: 28,
city: "San Francisco",
hobbies: ["reading", "gaming"]
};
// Basic conversion
const jsonString = JSON.stringify(user);
console.log(jsonString);
// {"name":"Alice","age":28,"city":"San Francisco","hobbies":["reading","gaming"]}
// With formatting (2-space indentation)
const formattedJson = JSON.stringify(user, null, 2);
console.log(formattedJson);
// {
// "name": "Alice",
// "age": 28,
// "city": "San Francisco",
// "hobbies": ["reading", "gaming"]
// }
// With replacer function
const filtered = JSON.stringify(user, (key, value) => {
if (key === "age") return undefined; // Exclude age
return value;
});
console.log(filtered); // {"name":"Alice","city":"San Francisco","hobbies":["reading","gaming"]}
// Parsing JSON back to object
const parsed = JSON.parse(jsonString);
console.log(parsed.name); // "Alice"
// Handle errors
try {
const invalid = JSON.parse("{ invalid json }");
} catch (error) {
console.log("Invalid JSON:", error.message);
}
28. What is debouncing in JavaScript?
Debouncing is a technique that delays the execution of a function until a specified time has passed since it was last called. It’s useful for optimizing performance in scenarios with frequent events like search input or window resize.
// Simple debounce implementation
function debounce(func, delay) {
let timeoutId;
return function(...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
func(...args);
}, delay);
};
}
// Example: Search input
const searchInput = document.getElementById("search");
const handleSearch = debounce((query) => {
console.log("Searching for:", query);
// Perform API call
}, 500);
searchInput.addEventListener("input", (e) => {
handleSearch(e.target.value);
});
// Example: Window resize
const handleResize = debounce(() => {
console.log("Window resized");
// Recalculate layout
}, 300);
window.addEventListener("resize", handleResize);
// Using with event handlers
const saveData = debounce((data) => {
console.log("Saving:", data);
// Send to server
}, 1000);
document.getElementById("editor").addEventListener("change", (e) => {
saveData(e.target.value);
});
29. What is throttling in JavaScript?
Throttling is a technique that ensures a function is executed at most once in a specified time interval, regardless of how many times it’s called. It’s useful for controlling high-frequency events like scroll or mouse movement.
// Simple throttle implementation
function throttle(func, limit) {
let isThrottled = false;
return function(...args) {
if (!isThrottled) {
func(...args);
isThrottled = true;
setTimeout(() => {
isThrottled = false;
}, limit);
}
};
}
// Example: Scroll event
const handleScroll = throttle(() => {
console.log("Scroll event triggered");
// Update UI based on scroll
}, 1000);
window.addEventListener("scroll", handleScroll);
// Example: Click button
const handleClick = throttle(() => {
console.log("Button clicked");
// Process click
}, 2000);
document.getElementById("button").addEventListener("click", handleClick);
// Example: Mouse movement
const handleMouseMove = throttle((event) => {
console.log("Mouse at:", event.clientX, event.clientY);
// Update tracking data
}, 500);
document.addEventListener("mousemove", handleMouseMove);
// Comparison of debounce vs throttle
// Debounce: Waits for 500ms of inactivity
// Throttle: Executes at most every 500ms
30. Explain variable scope and scope chain in JavaScript.
Scope defines the accessibility of variables within your code. JavaScript has three types of scope: global, function (local), and block scope. The scope chain determines which variables are accessible at any point in the code by looking up the scope hierarchy.
// Global scope
const globalVar = "I'm global";
function outer() {
// Function scope
const outerVar = "I'm outer";
function inner() {
// Block/Function scope
const innerVar = "I'm inner";
console.log(innerVar); // "I'm inner"
console.log(outerVar); // "I'm outer"
console.log(globalVar); // "I'm global"
}
inner();
// console.log(innerVar); // Error: innerVar is not defined
}
outer();
// console.log(outerVar); // Error: outerVar is not defined
// Block scope with let and const
if (true) {
let blockVar = "Block scope";
const blockConst = "Also block scope";
var blockVarOld = "Function scope";
}
// console.log(blockVar); // Error: blockVar is not defined
// console.log(blockConst); // Error: blockConst is not defined
console.log(blockVarOld); // "Function scope" (hoisted to function scope)
// Scope chain example
const level1 = "Level 1";
function function1() {
const level2 = "Level 2";
function function2() {
const level3 = "Level 3";
console.log(level3); // Own scope
console.log(level2); // Parent scope
console.log(level1); // Global scope
// Scope chain: level3 → level2 → level1 (global)
}
function2();
}
function1();
// Lexical scope (scope based on where function is defined)
const name = "Global";
function printName() {
console.log(name); // Lexical scope: refers to global 'name'
}
{
const name = "Block";
printName(); // Still prints "Global" because printName is defined globally
}
Scenario-Based Interview Questions
Scenario 1: Optimizing Performance at a Large-Scale E-Commerce Platform
You are developing features for Flipkart’s checkout page. During testing, you notice that searching for products causes the browser to freeze when users type quickly. How would you solve this problem?
Answer: This is a debouncing scenario. Implement a debounce function to limit the frequency of search API calls. For every keystroke, clear the previous timeout and set a new one. Only execute the search after 500ms of inactivity, significantly reducing unnecessary API requests and improving the user experience.
Scenario 2: Handling Multiple Asynchronous API Calls
You need to fetch user profile, user orders, and user reviews from three different endpoints before rendering a dashboard. The requests are independent and can be made simultaneously. Which approach is more efficient: sequential or parallel execution?
Answer: Use parallel execution with Promise.all() or async/await with Promise.all(). Sequential execution would take the sum of all three request times, while parallel execution takes only the time of the longest request. This significantly improves performance. Handle errors gracefully; if one request fails, decide whether to fail the entire operation or gracefully degrade by showing partial data.
Scenario 3: Building a Reusable Utility Module
You’re building a utility library for Zoho that includes functions like formatting dates, validating emails, and calculating discounts. How would you structure this to allow developers to import only what they need?
Answer: Use named exports for each utility function instead of a default export. This allows developers to import specific functions using destructuring, reducing bundle size. Create separate files for logical groupings and use ES6 modules for clean organization. Developers can then use import { formatDate, validateEmail } from “./utils” instead of importing the entire library.
Conclusion
Mastering these 30 JavaScript interview questions will prepare you for technical interviews across companies of all sizes. Focus on understanding not just the “what” but the “why” behind each concept. Practice writing code, debug actively, and always test edge cases. Whether you’re interviewing for positions at Atlassian, Adobe, or emerging startups, these fundamentals remain essential. Regular practice with real-world scenarios will boost your confidence and effectiveness in technical interviews.