HTML & JS Topic
Top 30 JavaScript Interview Questions & Answers
Core JavaScript Concepts
1. What is the difference between let, const, and var?
Answer:
-
var: Function-scoped, hoisted, can be redeclared, initialized withundefined -
let: Block-scoped, hoisted but not initialized (TDZ), cannot be redeclared in same scope -
const: Block-scoped, must be initialized, cannot be reassigned (but object properties can be modified)
javascript
// Temporal Dead Zone example
console.log(x); // ReferenceError (TDZ)
let x = 5;
2. Explain closures with an example
Answer: A closure is a function that retains access to variables from its outer (enclosing) scope even after the outer function has returned.
javascript
function outer() {
let count = 0;
return function inner() {
count++;
return count;
};
}
const counter = outer();
console.log(counter()); // 1
console.log(counter()); // 2
// 'count' persists due to closure
3. What is hoisting in JavaScript?
Answer: JavaScript's behavior of moving declarations to the top of their scope during compilation.
-
Function declarations: Fully hoisted (can be called before declaration)
-
varvariables: Hoisted but initialized asundefined -
let/const: Hoisted but not initialized (Temporal Dead Zone) -
Function expressions: Follow variable hoisting rules
4. Explain the this keyword in different contexts
Answer: this refers to the execution context:
javascript
// 1. Global context: `this` refers to window/global object
// 2. Object method: `this` refers to the object
const obj = {
name: 'John',
greet() { return `Hello, ${this.name}`; }
};
// 3. Constructor function: `this` refers to new instance
function Person(name) { this.name = name; }
// 4. Arrow function: `this` is lexically bound (inherits from parent scope)
// 5. Event handler: `this` refers to the element that received the event
// 6. Explicit binding: call(), apply(), bind()
5. What are promises and how do they work?
Answer: Promises represent the eventual completion or failure of an asynchronous operation.
javascript
const promise = new Promise((resolve, reject) => {
setTimeout(() => resolve('Success!'), 1000);
});
promise
.then(result => console.log(result))
.catch(error => console.error(error))
.finally(() => console.log('Done'));
// Promise states: pending, fulfilled, rejected
Intermediate JavaScript Questions
6. Explain the event loop and how async code works
Answer: JavaScript has a single-threaded event loop with:
-
Call Stack: Executes synchronous code
-
Web APIs: Browser-provided APIs (setTimeout, DOM events, HTTP requests)
-
Callback Queue: Holds callbacks from Web APIs
-
Microtask Queue: For promises and MutationObserver (higher priority)
Execution order: Call Stack → Microtasks → Callback Queue
7. What is the difference between == and ===?
Answer:
-
==(loose equality): Performs type coercion before comparison -
===(strict equality): No type coercion, compares type and value
javascript
0 == false // true (coercion)
0 === false // false (different types)
null == undefined // true
null === undefined // false
8. Explain call, apply, and bind methods
Answer: Methods to explicitly set this value:
javascript
const person = { name: 'Alice' };
function greet(greeting, punctuation) {
return `${greeting}, ${this.name}${punctuation}`;
}
// call(): Invokes immediately with arguments passed individually
greet.call(person, 'Hello', '!'); // "Hello, Alice!"
// apply(): Invokes immediately with arguments as array
greet.apply(person, ['Hi', '.']); // "Hi, Alice."
// bind(): Returns new function with bound context
const boundGreet = greet.bind(person, 'Hey');
boundGreet('?'); // "Hey, Alice?"
9. What are arrow functions and their limitations?
Answer:
Features:
-
Shorter syntax
-
Lexical
this(inherits from parent scope) -
No
argumentsobject -
Cannot be used as constructors
Limitations:
-
No own
this,super,arguments -
Cannot use
newkeyword -
Not suitable for object methods when dynamic
thisis needed -
No function hoisting (assigned to variables)
10. Explain prototypal inheritance
Answer: JavaScript uses prototype-based inheritance where objects inherit from other objects.
javascript
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
return `${this.name} makes a sound`;
};
function Dog(name) {
Animal.call(this, name); // Call parent constructor
}
// Set up prototype chain
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.speak = function() {
return `${this.name} barks`;
};
const dog = new Dog('Rex');
console.log(dog.speak()); // "Rex barks"
Advanced JavaScript Questions
11. What is the event delegation pattern?
Answer: Attaching a single event listener to a parent element to handle events from multiple child elements, leveraging event bubbling.
javascript
document.getElementById('parent').addEventListener('click', function(e) {
if (e.target.matches('button')) {
console.log('Button clicked:', e.target.id);
}
});
Benefits: Better performance, works for dynamically added elements.
12. Explain debounce and throttle functions
Answer:
Debounce: Groups multiple calls into one after delay
Throttle: Ensures function is called at most once per specified period
javascript
// Debounce implementation
function debounce(func, delay) {
let timeout;
return function(...args) {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), delay);
};
}
// Throttle implementation
function throttle(func, limit) {
let inThrottle;
return function(...args) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
13. What are generators and how do they work?
Answer: Functions that can be paused and resumed using yield.
javascript
function* numberGenerator() {
yield 1;
yield 2;
yield 3;
}
const gen = numberGenerator();
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // 3
console.log(gen.next().done); // true
// Use case: Lazy evaluation, infinite sequences
function* infiniteSequence() {
let i = 0;
while (true) {
yield i++;
}
}
14. Explain the Module Pattern
Answer: A design pattern to create private and public encapsulated code.
javascript
const Module = (function() {
// Private
let privateVar = 'secret';
function privateMethod() {
return privateVar;
}
// Public
return {
publicMethod: function() {
return privateMethod();
},
publicVar: 'accessible'
};
})();
console.log(Module.publicMethod()); // "secret"
console.log(Module.privateVar); // undefined
15. What are Web Workers?
Answer: JavaScript running in background threads without blocking the UI.
javascript
// Main thread
const worker = new Worker('worker.js');
worker.postMessage('Hello Worker');
worker.onmessage = (e) => console.log(e.data);
// worker.js
self.onmessage = (e) => {
const result = heavyComputation(e.data);
self.postMessage(result);
};
Limitations: No DOM access, communicate via message passing.
ES6+ Modern JavaScript
16. Explain destructuring assignment
Answer: Extract values from arrays or properties from objects into distinct variables.
javascript
// Array destructuring
const [first, second, ...rest] = [1, 2, 3, 4, 5];
// Object destructuring
const { name, age, ...otherProps } = {
name: 'John',
age: 30,
city: 'NYC'
};
// Parameter destructuring
function greet({ name, age }) {
return `Hello ${name}, age ${age}`;
}
// Default values
const { title = 'Default' } = {};
17. What are template literals?
Answer: String literals allowing embedded expressions and multi-line strings.
javascript
const name = 'Alice';
const age = 25;
// Basic usage
const greeting = `Hello, ${name}!`;
// Multi-line
const message = `
Name: ${name}
Age: ${age}
Next year: ${age + 1}
`;
// Tagged templates
function highlight(strings, ...values) {
return strings.reduce((result, str, i) =>
`${result}${str}<strong>${values[i] || ''}</strong>`, '');
}
18. Explain spread and rest operators
Answer:
Spread (...): Expands iterables into individual elements
javascript
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 }; // { a: 1, b: 2, c: 3 }
// Function arguments
Math.max(...[1, 5, 3]); // 5
Rest (...): Collects multiple elements into an array
javascript
function sum(...numbers) {
return numbers.reduce((a, b) => a + b);
}
sum(1, 2, 3, 4); // 10
const [first, ...others] = [1, 2, 3, 4];
19. What are Map and Set objects?
Answer:
Map: Key-value pairs with any type as key
javascript
const map = new Map();
map.set('key', 'value');
map.set({}, 'object key');
map.has('key'); // true
map.size; // 2
Set: Collection of unique values
javascript
const set = new Set([1, 2, 3, 3, 2]); // {1, 2, 3}
set.add(4);
set.has(3); // true
set.size; // 4
20. Explain async/await
Answer: Syntactic sugar over promises for asynchronous code.
javascript
async function fetchData() {
try {
const response = await fetch('api/data');
const data = await response.json();
return data;
} catch (error) {
console.error('Error:', error);
throw error;
}
}
// Multiple promises
async function fetchAll() {
const [user, posts] = await Promise.all([
fetch('/user'),
fetch('/posts')
]);
return { user, posts };
}
// Async arrow functions
const fetchUser = async (id) => {
const response = await fetch(`/users/${id}`);
return response.json();
};
Error Handling & Debugging
21. What are the different error types in JavaScript?
Answer:
javascript
// 1. SyntaxError: Invalid syntax
// const 123abc = 5;
// 2. ReferenceError: Undefined variable
// console.log(undefinedVariable);
// 3. TypeError: Wrong type operation
// null.someMethod();
// 4. RangeError: Invalid range
// new Array(-1);
// 5. URIError: Invalid URI handling
// decodeURI('%');
// 6. AggregateError: Multiple errors (Promise.any)
// 7. Custom errors
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = 'ValidationError';
}
}
22. How does error handling work with promises?
Answer:
javascript
// Using .catch()
fetch('api/data')
.then(response => response.json())
.catch(error => console.error('Fetch failed:', error));
// Using async/await
async function getData() {
try {
const response = await fetch('api/data');
return await response.json();
} catch (error) {
// Handle network errors
throw new Error('Data fetch failed');
}
}
// Promise-specific methods
Promise.all([p1, p2]) // Fails if any fail
.catch(error => console.error(error));
Promise.allSettled([p1, p2]) // Always resolves
.then(results => console.log(results));
23. What is the difference between null and undefined?
Answer:
-
undefined: Variable declared but not assigned, missing property, function without return -
null: Intentional absence of value, explicitly set by programmer -
Typeof:
typeof undefined→ "undefined",typeof null→ "object" (historical bug) -
Usage:
nullfor intentional emptiness,undefinedfor unintentional missing values
Performance & Optimization
24. How do you measure JavaScript performance?
Answer:
javascript
// 1. Console.time()
console.time('operation');
// Code to measure
console.timeEnd('operation');
// 2. Performance API
const start = performance.now();
// Code to measure
const duration = performance.now() - start;
// 3. Memory usage
console.memory; // Shows heap size
// 4. Chrome DevTools:
// - Performance tab
// - Memory tab
// - Lighthouse audits
// - Coverage tab
// 5. RequestAnimationFrame for animations
25. What is memoization and how to implement it?
Answer: Caching function results for same inputs.
javascript
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;
};
}
// Example: Fibonacci
const memoizedFib = memoize(function fib(n) {
if (n <= 1) return n;
return memoizedFib(n - 1) + memoizedFib(n - 2);
});
DOM & Browser API Questions
26. Explain the event bubbling and capturing phases
Answer:
javascript
// Event flow: Capturing → Target → Bubbling
// Default: Bubbling (inner to outer)
document.querySelector('.outer').addEventListener('click',
() => console.log('Bubbling: Outer'), false);
document.querySelector('.inner').addEventListener('click',
(e) => {
console.log('Target: Inner');
e.stopPropagation(); // Stops bubbling
}, false);
// Capturing phase (true)
document.querySelector('.outer').addEventListener('click',
() => console.log('Capturing: Outer'), true);
27. What is the difference between localStorage, sessionStorage, and cookies?
Answer:
| Feature | localStorage | sessionStorage | Cookies |
|---|---|---|---|
| Capacity | 5-10MB | 5-10MB | 4KB |
| Expiration | Never | Tab close | Manual set |
| Server Access | No | No | Yes (auto-sent) |
| Scope | Origin | Origin + Tab | Domain/path |
| API | setItem/getItem | setItem/getItem | document.cookie |
28. How does JavaScript handle memory management?
Answer:
-
Automatic garbage collection (mark-and-sweep algorithm)
-
Reference counting (deprecated for circular references)
-
Memory leaks common causes:
-
Global variables
-
Forgotten timers/intervals
-
DOM references in closures
-
Event listeners not removed
-
Circular references
-
Tools: Chrome DevTools Memory tab, Heap Snapshots
Advanced Topics
29. What are proxies and reflect in JavaScript?
Answer: Proposals for meta-programming.
javascript
// Proxy: Custom behavior for fundamental operations
const handler = {
get(target, prop) {
return prop in target ? target[prop] : 'Not found';
},
set(target, prop, value) {
if (prop === 'age' && typeof value !== 'number') {
throw new Error('Age must be a number');
}
target[prop] = value;
return true;
}
};
const person = new Proxy({}, handler);
person.age = 30;
console.log(person.name); // "Not found"
// Reflect: Built-in object providing methods for interceptable operations
Reflect.set(person, 'name', 'John');
Reflect.has(person, 'name'); // true
30. Explain the Observer Pattern (or Pub/Sub Pattern)
Answer: A pattern where objects subscribe to events and get notified when events occur.
javascript
class EventEmitter {
constructor() {
this.events = {};
}
on(event, listener) {
if (!this.events[event]) this.events[event] = [];
this.events[event].push(listener);
}
emit(event, ...args) {
if (this.events[event]) {
this.events[event].forEach(listener => listener(...args));
}
}
off(event, listenerToRemove) {
if (this.events[event]) {
this.events[event] = this.events[event]
.filter(listener => listener !== listenerToRemove);
}
}
}
// Usage
const emitter = new EventEmitter();
emitter.on('data', (data) => console.log('Received:', data));
emitter.emit('data', { id: 1 }); // "Received: {id: 1}"
Bonus: Common JavaScript Puzzles
What will this code output?
javascript
console.log(1);
setTimeout(() => console.log(2), 0);
Promise.resolve().then(() => console.log(3));
console.log(4);
// Output: 1, 4, 3, 2
// Why: Microtasks (promises) run before macrotasks (setTimeout)
Implement a deep clone function
javascript
function deepClone(obj, hash = new WeakMap()) {
if (obj === null || typeof obj !== 'object') return obj;
if (hash.has(obj)) return hash.get(obj);
if (obj instanceof Date) return new Date(obj);
if (obj instanceof RegExp) return new RegExp(obj);
const clone = Array.isArray(obj) ? [] : {};
hash.set(obj, clone);
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
clone[key] = deepClone(obj[key], hash);
}
}
return clone;
}
Comments (0)
No comments yet. Be the first to comment!