JavaScript is the most-interviewed programming language in India for web and full-stack developer roles. Unlike Java or Python where interview questions follow a fairly predictable pattern, JavaScript interviews have a much wider surface area: closures, prototypes, the event loop, async patterns, ES6+ features, and: at many companies: React and TypeScript on top. This guide covers the questions actually asked in 2026, ranked from fresher-level to senior-level, with answers you can use directly.
Core JavaScript: Questions Asked at Every Level
1. What is the difference between var, let, and const?
| | var | let | const | |---|---|---|---| | Scope | Function | Block | Block | | Hoisted | Yes (undefined) | Yes (TDZ) | Yes (TDZ) | | Re-declarable | Yes | No | No | | Re-assignable | Yes | Yes | No |
TDZ = Temporal Dead Zone: accessing a let/const before its declaration throws ReferenceError.
2. What is hoisting? JavaScript moves variable and function declarations to the top of their scope before execution. `var` declarations are hoisted and initialised to `undefined`. Function declarations are fully hoisted. `let` and `const` are hoisted but remain in the TDZ until the declaration is reached. ```js console.log(x); // undefined (var is hoisted) var x = 5; console.log(y); // ReferenceError (let is in TDZ) let y = 5; ```
3. What is a closure? A closure is a function that retains access to its outer scope even after the outer function has returned. ```js function counter() { let count = 0; return function() { count++; return count; }; } const increment = counter(); console.log(increment()); // 1 console.log(increment()); // 2 // count persists because increment closes over it ``` Closures are used for: data privacy, factory functions, memoisation, event handlers.
4. What is the difference between == and ===? `==` performs type coercion before comparison. `===` (strict equality) does not. ```js 0 == false // true (0 coerces to false) 0 === false // false (different types) null == undefined // true null === undefined // false ``` Always use `===` unless you specifically need type coercion.
5. What is the difference between null and undefined?
- `undefined`: variable declared but not assigned, or function parameter not provided
- `null`: intentional absence of value; must be explicitly assigned
- `typeof null === 'object'`: this is a known JavaScript bug from the original 1995 implementation
6. What are the falsy values in JavaScript? `false`, `0`, `''` (empty string), `null`, `undefined`, `NaN`. Everything else is truthy, including `[]`, `{}`, `'0'`.
Event Loop, Async, and Promises
The event loop is one of the most common interview topics for JavaScript roles at product companies.
7. Explain the JavaScript event loop. JavaScript is single-threaded. The event loop manages how asynchronous tasks are executed:
- Call stack: where synchronous code executes
- Web APIs: browser provides async APIs (setTimeout, fetch, DOM events): they run outside the JS thread
- Callback queue (macro-task queue): callbacks from setTimeout, setInterval wait here
- Microtask queue: Promise `.then` callbacks, `queueMicrotask`: higher priority than macro-task queue
Execution order: Call stack empties → drain microtask queue completely → take ONE macro-task → drain microtask queue again → repeat.
```js console.log('1'); // sync setTimeout(() => console.log('2'), 0); // macro-task Promise.resolve().then(() => console.log('3')); // microtask console.log('4'); // sync // Output: 1, 4, 3, 2 ```
8. What is the difference between Promise and async/await? Async/await is syntactic sugar over Promises: it makes asynchronous code look synchronous: ```js // Promise chain fetch('/api/user') .then(res => res.json()) .then(data => console.log(data)) .catch(err => console.error(err));
// async/await equivalent async function getUser() { try { const res = await fetch('/api/user'); const data = await res.json(); console.log(data); } catch (err) { console.error(err); } } ```
9. What is Promise.all vs Promise.allSettled?
- `Promise.all([p1, p2, p3])`: resolves when ALL resolve; rejects immediately if ANY rejects
- `Promise.allSettled([p1, p2, p3])`: waits for ALL to settle (resolve or reject); never short-circuits
- Use `Promise.all` when you need all results and any failure is a stop-everything failure.
- Use `Promise.allSettled` when you want to handle partial failures gracefully.
10. What is a callback hell and how do you avoid it? Nested callbacks that become deeply indented and hard to read. Avoid with Promises, async/await, or by extracting callbacks into named functions.
ES6+ Features: The Most Interviewed
11. What are arrow functions and how do they differ from regular functions?
- No own `this`: arrow functions inherit `this` from the enclosing lexical scope
- Cannot be used as constructors (no `new`)
- No `arguments` object
- Shorter syntax
```js const obj = { value: 42, regular: function() { return this.value; }, // this = obj arrow: () => this.value, // this = outer scope (window/undefined in strict) }; console.log(obj.regular()); // 42 console.log(obj.arrow()); // undefined ```
12. What is destructuring? ```js // Object destructuring const { name, age = 25 } = user; // default value if undefined
// Array destructuring const [first, , third] = [1, 2, 3]; // skip second
// In function parameters function greet({ name, city = 'Bengaluru' }) { return `${name} from ${city}`; } ```
13. What is the spread operator vs rest parameters? ```js // Spread: expands an iterable const arr = [1, 2, 3]; const arr2 = [...arr, 4, 5]; // [1, 2, 3, 4, 5] const obj2 = { ...obj1, newProp: true }; // shallow clone + add
// Rest: collects remaining arguments into an array function sum(first, ...rest) { return first + rest.reduce((a, b) => a + b, 0); } ```
14. What are template literals? Backtick strings that support interpolation and multi-line content: ```js const name = 'Priya'; console.log(`Hello, ${name}! You have ${2 + 2} messages.`); ```
15. What is optional chaining (?.) and nullish coalescing (??)? (ES2020) ```js // Without optional chaining const city = user && user.address && user.address.city;
// With optional chaining const city = user?.address?.city; // undefined if any step is null/undefined
// Nullish coalescing: returns right side only if left is null or undefined const name = user.name ?? 'Anonymous'; // NOT the same as || (which triggers on '') ```
JavaScript technical interviews test both knowledge and verbal explanation: can you explain what a closure is clearly, not just write one? HireStepX's voice mock interviews train you to articulate technical concepts under pressure, the skill that converts good knowledge into strong interview performance.
Practice freePrototypes, `this`, and Object-Oriented JS
16. What is prototypal inheritance in JavaScript? Every JavaScript object has a `[[Prototype]]` (accessible via `_proto_` or `Object.getPrototypeOf()`). When a property is not found on the object, JavaScript looks up the prototype chain. ```js const animal = { breathes: true }; const dog = Object.create(animal); dog.speaks = 'bark'; console.log(dog.breathes); // true: found on prototype ```
17. What is `this` in JavaScript? `this` depends on call context:
- Regular function call: global object (window in browser, undefined in strict mode)
- Method call: the object before the dot
- Arrow function: lexical `this` from enclosing scope
- `new` call: the newly created object
- `call/apply/bind`: explicitly provided object
18. What is the difference between call, apply, and bind? ```js function greet(greeting, punctuation) { return `${greeting}, ${this.name}${punctuation}`; } const user = { name: 'Rahul' }; greet.call(user, 'Hello', '!'); // immediate; args as list greet.apply(user, ['Hello', '!']); // immediate; args as array const boundGreet = greet.bind(user); // returns new function; call later boundGreet('Hello', '!'); ```
19. What is the difference between class and prototype-based inheritance in JS? ES6 `class` syntax is syntactic sugar over prototype-based inheritance: it does not introduce a new OOP model. Under the hood, class methods are added to `ClassName.prototype`.
20. What is event delegation? Instead of adding a listener to every child element, add one listener to a parent and use `event.target` to identify which child was clicked: ```js document.getElementById('list').addEventListener('click', (e) => { if (e.target.tagName === 'LI') { console.log('Clicked:', e.target.textContent); } }); // Works even for dynamically added <li> elements ```
JavaScript Coding Problems Asked in Interviews
Problem 1: Debounce function 'Implement a debounce function that delays invoking fn until after wait ms have passed since the last invocation.' ```js function debounce(fn, wait) { let timer; return function(...args) { clearTimeout(timer); timer = setTimeout(() => fn.apply(this, args), wait); }; } // Usage: const search = debounce(fetchResults, 300); ```
Problem 2: Flatten a nested array ```js // Recursive function flatten(arr) { return arr.reduce((acc, val) => Array.isArray(val) ? [...acc, ...flatten(val)] : [...acc, val] , []); } // Or: arr.flat(Infinity): built-in ```
Problem 3: Deep clone an object ```js // JSON approach (loses functions, Dates become strings, undefined dropped) const clone = JSON.parse(JSON.stringify(obj)); // Better: structuredClone(): ES2022, handles Date, Map, Set const clone = structuredClone(obj); ```
Problem 4: Memoize a function ```js function memoize(fn) { const cache = new Map(); return function(...args) { const key = JSON.stringify(args); if (cache.has(key)) return cache.get(key); const result = fn.apply(this, args); cache.set(key, result); return result; }; } ```
Problem 5: Implement Promise.all from scratch ```js function promiseAll(promises) { return new Promise((resolve, reject) => { const results = []; let resolved = 0; if (promises.length === 0) return resolve([]); promises.forEach((p, i) => { Promise.resolve(p).then(val => { results[i] = val; if (++resolved === promises.length) resolve(results); }).catch(reject); }); }); } ```
Frequently asked questions
Practice these questions on HireStepX