JavaScript Interview Questions
Most commonly asked — Technology Analyst interview prep
Part 1 — Language Fundamentals
Q: var vs let vs const? A: var is function-scoped and can be redeclared/reassigned, hoisted with 'undefined'. let is
block-scoped, can be reassigned but not redeclared in the same scope. const is block-scoped, cannot be reassigned
(but object/array contents CAN still be mutated).
var x = 1;
let y = 2;
const z = 3;
z = 4; // Error: Assignment to constant variable
const arr = [1,2];
[Link](3); // OK — the array contents can change, the binding can't
Q: What is hoisting? A: JavaScript moves variable and function declarations to the top of their scope before
execution. var declarations are hoisted and initialized as undefined. let/const are hoisted but stay in the 'temporal
dead zone' until their line executes — accessing them earlier throws an error.
Q: What is the difference between == and ===? A: == compares values with type coercion (converts types before
comparing). === compares both value and type, with no coercion. Always prefer === in real code to avoid
unexpected bugs.
0 == '0' // true (coercion)
0 === '0' // false (different types)
null == undefined // true
null === undefined // false
Q: What is a closure? A: A function that remembers and can access variables from its outer (enclosing) scope even
after that outer function has finished executing.
function outer() {
let count = 0;
return function inner() {
count++;
return count;
};
}
const counter = outer();
[Link](counter()); // 1
[Link](counter()); // 2 — 'count' is remembered between calls
Q: What is 'this' in JavaScript? A: 'this' refers to the object that is currently executing the function. Its value
depends on HOW a function is called, not where it's defined — e.g., as a method (this = the object), standalone (this
= undefined in strict mode / global object otherwise), or with arrow functions (this = inherited from the enclosing
scope).
Q: Arrow functions vs regular functions? A: Arrow functions don't have their own 'this' — they inherit it from the
surrounding scope. They also can't be used as constructors and don't have their own 'arguments' object. Regular
functions have their own 'this' determined by how they're called.
const obj = {
name: 'Harsh',
regular: function() { return [Link]; }, // 'this' = obj
arrow: () => { return [Link]; } // 'this' = outer scope,
likely undefined
};
Q: What is the Event Loop? A: JavaScript is single-threaded. The Event Loop allows non-blocking asynchronous
behavior by moving completed async operations (from the Callback Queue / Microtask Queue) onto the Call Stack
once it's empty, so code doesn't freeze while waiting on things like network requests or timers.
Q: Call Stack vs Callback Queue vs Microtask Queue? A: Call Stack executes synchronous code line by line.
Once a Promise resolves, its .then() callback goes into the Microtask Queue. setTimeout/setInterval callbacks go
into the (macro)task/Callback Queue. Microtasks are processed before the next macrotask, after the current call
stack is empty.
Q: What is the difference between null and undefined? A: undefined means a variable has been declared but not
assigned a value. null is an intentional assignment representing 'no value' — you explicitly set it.
Q: What are template literals? A: String literals using backticks that allow embedded expressions and multi-line
strings.
const name = 'Harsh';
[Link](`Hello, ${name}! You have ${2+2} messages.`);
Q: What is destructuring? A: A syntax to unpack values from arrays or properties from objects into distinct
variables.
const { name, age } = { name: 'Harsh', age: 22 };
const [first, second] = [10, 20];
Q: What is the spread operator vs rest parameter? A: Spread (...) expands an iterable into individual elements.
Rest (...) collects multiple elements into a single array — used in function parameters.
// spread
const arr1 = [1,2,3];
const arr2 = [...arr1, 4,5]; // [1,2,3,4,5]
// rest
function sum(...nums) {
return [Link]((a,b) => a+b, 0);
}
sum(1,2,3); // 6
Part 2 — Asynchronous JavaScript
Q: What is a Promise? A: An object representing the eventual completion (or failure) of an asynchronous
operation, with three states: pending, fulfilled, rejected.
const promise = new Promise((resolve, reject) => {
setTimeout(() => resolve('Done!'), 1000);
});
[Link](result => [Link](result));
Q: What is async/await? A: Syntactic sugar over Promises that lets you write asynchronous code that looks
synchronous. 'async' marks a function as returning a Promise; 'await' pauses execution until the Promise resolves.
async function fetchData() {
try {
const response = await fetch('[Link]
const data = await [Link]();
[Link](data);
} catch (error) {
[Link]('Error:', error);
}
}
Q: Callback vs Promise vs async/await? A: Callback: a function passed as an argument, run once the operation
completes — can lead to 'callback hell' with nested calls. Promise: a cleaner, chainable object representing a future
value, avoiding deep nesting. async/await: builds on Promises for even more readable, synchronous-looking code.
Q: What does [Link]() do? A: Takes an array of Promises and resolves when ALL of them resolve (or rejects
immediately if any one rejects), returning an array of results in order.
Part 3 — Arrays, Objects & Common Methods
Q: map vs forEach vs filter vs reduce? A: map returns a new array by transforming each element. forEach just
iterates, returns undefined (used for side effects). filter returns a new array with elements passing a condition. reduce
accumulates values into a single result.
const nums = [1,2,3,4];
[Link](n => n*2); // [2,4,6,8]
[Link](n => n % 2 === 0); // [2,4]
[Link]((acc,n) => acc+n, 0); // 10
[Link](n => [Link](n)); // just logs, returns undefined
Q: How do you clone an object? A: Shallow clone: { ...obj } or [Link]({}, obj). Deep clone (nested
objects): [Link]([Link](obj)) for simple cases, or structuredClone(obj) in modern environments.
Q: What is the difference between slice and splice? A: slice() returns a shallow copy of a portion of an array
WITHOUT modifying the original. splice() changes the original array by removing/replacing/adding elements.
const arr = [1,2,3,4,5];
[Link](1,3); // [2,3] — original arr unchanged
[Link](1,2); // removes [2,3] from arr — arr is now [1,4,5]
Q: What are truthy and falsy values? A: Falsy values: false, 0, '', null, undefined, NaN. Everything else is truthy
— including '0' (string) and empty arrays/objects [] {}.
Part 4 — Common Coding Questions (be ready to write these
live)
Reverse a string:
function reverseString(str) {
return [Link]('').reverse().join('');
}
Check if a string is a palindrome:
function isPalindrome(str) {
const clean = [Link]().replace(/[^a-z0-9]/g, '');
return clean === [Link]('').reverse().join('');
}
Find duplicates in an array:
function findDuplicates(arr) {
const seen = new Set();
const duplicates = new Set();
for (const item of arr) {
if ([Link](item)) [Link](item);
[Link](item);
}
return [...duplicates];
}
Debounce function (common frontend question):
function debounce(fn, delay) {
let timer;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(() => [Link](this, args), delay);
};
}
Part 5 — Conceptual Questions Often Used to Test Depth
Q: What is event delegation? A: Attaching a single event listener to a parent element instead of many listeners on
individual children, using event bubbling to handle events at the parent level. More efficient for dynamic lists of
elements.
Q: What is the DOM? A: The Document Object Model — a tree-like representation of an HTML page that
JavaScript can read and manipulate to change content, structure, and styling dynamically.
Q: What is JSON and why is it used? A: JavaScript Object Notation — a lightweight, text-based data format used
to exchange data between a client and server, easy for both humans and machines to read.
Q: What is NaN and how do you check for it? A: 'Not a Number' — the result of an invalid numeric operation.
Use [Link](value) rather than the global isNaN(), which coerces types and can give false positives.
Q: What is prototypal inheritance? A: Objects in JavaScript can inherit properties and methods directly from
other objects via a prototype chain, rather than through classes (though ES6 'class' syntax is sugar over this same
prototype system).
Practice Routine
● Rewrite each code snippet above from memory, don't just read it
● For each Q&A, say the answer out loud before checking it
● Pick 2-3 coding questions daily and solve them without looking, then compare
● Explain closures and the event loop out loud to someone (or yourself) — these trip people up most