- Published on
30 Most important javascript questions for interview
- Authors
- Name
- Mohit Verma
==
and ===
operators?
1. What is the difference between The ==
(equality) operator compares values after converting them to a common type, while the ===
(strict equality) operator compares both value and type without conversion.
0 == '0' // true (string '0' is converted to number 0)
0 === '0' // false (different types: number vs string)
null == undefined // true
null === undefined // false
2. Explain closures in JavaScript.
A closure is a function that remembers and accesses variables from its outer scope even after the outer function has finished execution. It combines a function with references to its surrounding state.
function createCounter() {
let count = 0; // This variable is "closed over"
return function() {
count += 1;
return count;
};
}
const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
3. What is hoisting?
Hoisting is JavaScript's default behavior of moving declarations to the top of their scope during compilation. Variables declared with var
are hoisted and initialized with undefined
, while let
and const
are hoisted but not initialized (resulting in a "temporal dead zone").
console.log(x); // undefined (hoisted but not initialized)
var x = 5;
console.log(y); // ReferenceError: Cannot access 'y' before initialization
let y = 5;
4. Explain event bubbling and capturing.
Event bubbling is when an event starts at the target element and bubbles up through parent elements. Event capturing is when an event starts at the top element and trickles down to the target.
// Third parameter controls capturing vs bubbling:
// true = capturing phase, false/omitted = bubbling phase
element.addEventListener('click', handler, true); // Capturing
element.addEventListener('click', handler); // Bubbling (default)
// Stop event propagation
function handler(e) {
e.stopPropagation();
}
5. What is the prototype chain?
The prototype chain is JavaScript's inheritance mechanism. When a property is accessed on an object, JavaScript looks for it on the object itself. If not found, it looks at the object's prototype, then that prototype's prototype, and so on until it reaches Object.prototype
.
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
return `Hello, I'm ${this.name}`;
};
const alice = new Person('Alice');
console.log(alice.sayHello()); // "Hello, I'm Alice"
// sayHello is not on alice object directly, but on its prototype
this
keyword.
6. Explain the this
refers to the object that is currently executing the function. Its value depends on how the function is called:
// In a regular function, 'this' refers to the global object (window in browsers)
function regular() {
console.log(this);
}
// In a method, 'this' refers to the object the method belongs to
const obj = {
method: function() {
console.log(this); // refers to obj
}
};
// In an event handler, 'this' refers to the element that received the event
button.addEventListener('click', function() {
console.log(this); // refers to button
});
// With call/apply/bind, 'this' is explicitly set
regular.call({custom: true}); // 'this' is {custom: true}
// In arrow functions, 'this' is inherited from the surrounding scope
const arrowFn = () => console.log(this);
7. What is a Promise?
A Promise is an object representing the eventual completion or failure of an asynchronous operation. It can be in one of three states: pending, fulfilled, or rejected.
const fetchData = () => {
return new Promise((resolve, reject) => {
// Asynchronous operation
const success = true;
setTimeout(() => {
if (success) {
resolve('Data fetched successfully');
} else {
reject('Error fetching data');
}
}, 1000);
});
};
fetchData()
.then(data => console.log(data))
.catch(error => console.error(error));
8. What are arrow functions and how do they differ from regular functions?
Arrow functions are a concise syntax for writing functions in JavaScript. They differ from regular functions in several ways:
- No
this
binding (inherit from parent scope) - Can't be used as constructors (no
new
keyword) - No
arguments
object - No
super
ornew.target
- Can't change
this
with call/apply/bind
// Regular function
function add(a, b) {
return a + b;
}
// Arrow function
const add = (a, b) => a + b;
// 'this' behavior difference
const obj = {
name: 'Object',
regularMethod: function() {
console.log(this.name); // "Object"
},
arrowMethod: () => {
console.log(this.name); // undefined (inherits from parent scope)
}
};
null
and undefined
?
9. What is the difference between undefined
means a variable has been declared but not assigned a valuenull
is an explicit assignment value representing "no value" or "empty"
let a; // undefined (declared but not initialized)
let b = null; // null (explicitly assigned)
console.log(typeof undefined); // "undefined"
console.log(typeof null); // "object" (this is considered a bug in JavaScript)
10. What is the event loop?
The event loop is JavaScript's mechanism for handling asynchronous operations. It continuously checks the call stack and the callback queue, moving callbacks from the queue to the stack when the stack is empty.
console.log('Start');
setTimeout(() => {
console.log('Timeout callback');
}, 0);
Promise.resolve().then(() => {
console.log('Promise resolved');
});
console.log('End');
// Output:
// Start
// End
// Promise resolved
// Timeout callback
var
, let
, and const
.
11. Explain the differences between var
: Function-scoped, hoisted and initialized withundefined
let
: Block-scoped, hoisted but not initialized (temporal dead zone)const
: Block-scoped, must be initialized when declared, can't be reassigned
function example() {
// var is function-scoped
if (true) {
var x = 1;
let y = 2;
const z = 3;
}
console.log(x); // 1 (still accessible)
console.log(y); // ReferenceError (block-scoped)
console.log(z); // ReferenceError (block-scoped)
}
// const prevents reassignment but not mutation
const obj = { prop: 1 };
obj.prop = 2; // Valid
obj = {}; // TypeError: Assignment to constant variable
12. What is a callback function?
A callback function is a function passed into another function as an argument, which is then invoked inside the outer function to complete some kind of action.
function fetchData(callback) {
setTimeout(() => {
const data = { name: 'John', age: 30 };
callback(data);
}, 1000);
}
fetchData(function(data) {
console.log(data); // { name: 'John', age: 30 }
});
13. What is JSON and how do you work with it?
JSON (JavaScript Object Notation) is a lightweight data-interchange format. In JavaScript, you use JSON.stringify()
to convert objects to JSON strings and JSON.parse()
to convert JSON strings back to objects.
const person = {
name: 'Alice',
age: 25,
isStudent: true
};
// Object to JSON string
const jsonString = JSON.stringify(person);
console.log(jsonString); // '{"name":"Alice","age":25,"isStudent":true}'
// JSON string to object
const parsedPerson = JSON.parse(jsonString);
console.log(parsedPerson.name); // 'Alice'
bind
method?
14. What is the The bind
method creates a new function with a specified this
value and pre-set initial arguments. Unlike call
and apply
, bind
doesn't immediately execute the function but returns a new function.
const person = {
name: 'Alice',
greet: function() {
return `Hello, I'm ${this.name}`;
}
};
const greetFunction = person.greet;
console.log(greetFunction()); // "Hello, I'm undefined" (lost context)
const boundGreet = person.greet.bind(person);
console.log(boundGreet()); // "Hello, I'm Alice" (bound context)
// Pre-setting arguments
function multiply(a, b) {
return a * b;
}
const double = multiply.bind(null, 2);
console.log(double(4)); // 8 (2 * 4)
15. Explain async/await.
Async/await is syntactic sugar built on top of Promises, making asynchronous code look and behave more like synchronous code. An async
function always returns a Promise, and await
pauses execution until a Promise resolves.
async function fetchUserData() {
try {
const response = await fetch('https://api.example.com/users');
if (!response.ok) {
throw new Error('Network response was not ok');
}
const data = await response.json();
return data;
} catch (error) {
console.error('Failed to fetch user data:', error);
throw error;
}
}
// Using the async function
fetchUserData()
.then(data => console.log(data))
.catch(error => console.error(error));
function declaration
and function expression
?
16. What is the difference between A function declaration defines a named function and is hoisted, while a function expression defines a function as part of a larger expression (like a variable assignment) and is not hoisted.
// Function declaration - hoisted
console.log(sum(2, 3)); // 5
function sum(a, b) {
return a + b;
}
// Function expression - not hoisted
console.log(multiply(2, 3)); // ReferenceError: multiply is not defined
const multiply = function(a, b) {
return a * b;
};
17. What is a pure function?
A pure function is a function that:
- Given the same inputs, always returns the same output
- Has no side effects (doesn't modify external state)
// Pure function
function add(a, b) {
return a + b;
}
// Impure function (has side effects)
let total = 0;
function addToTotal(value) {
total += value; // Modifies external state
return total;
}
18. What is the spread operator?
The spread operator (...
) allows an iterable (array, string, object) to be expanded in places where zero or more arguments/elements/properties are expected.
// Array spread
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]
// Function arguments
function sum(a, b, c) {
return a + b + c;
}
const numbers = [1, 2, 3];
console.log(sum(...numbers)); // 6
// Object spread
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 }; // { a: 1, b: 2, c: 3 }
19. What is destructuring?
Destructuring is a JavaScript expression that allows extracting values from arrays or properties from objects into distinct variables.
// Array destructuring
const numbers = [1, 2, 3, 4, 5];
const [first, second, ...rest] = numbers;
console.log(first); // 1
console.log(second); // 2
console.log(rest); // [3, 4, 5]
// Object destructuring
const person = {
name: 'Alice',
age: 25,
city: 'New York'
};
const { name, age, city = 'Unknown' } = person;
console.log(name); // 'Alice'
// Function parameter destructuring
function displayPerson({ name, age }) {
console.log(`${name} is ${age} years old`);
}
displayPerson(person); // "Alice is 25 years old"
Map
object and how is it different from a regular object?
20. What is the Map
is a collection of key-value pairs where keys can be of any type (including objects), while object keys are always converted to strings. Maps maintain insertion order and are optimized for frequent additions/removals.
// Creating a Map
const userMap = new Map();
// Setting values
userMap.set('name', 'Alice');
userMap.set(42, 'answer');
userMap.set({}, 'empty object');
// Getting values
console.log(userMap.get('name')); // 'Alice'
// Checking if a key exists
console.log(userMap.has(42)); // true
// Size of the map
console.log(userMap.size); // 3
// Deleting entries
userMap.delete(42);
// Iterating over a Map
for (const [key, value] of userMap) {
console.log(`${key}: ${value}`);
}
21. What is a generator function?
A generator function can pause execution and resume later, yielding multiple values. It's defined using an asterisk (*
) and uses the yield
keyword.
function* countUpTo(max) {
let count = 0;
while (count < max) {
yield count++;
}
}
const counter = countUpTo(3);
console.log(counter.next()); // { value: 0, done: false }
console.log(counter.next()); // { value: 1, done: false }
console.log(counter.next()); // { value: 2, done: false }
console.log(counter.next()); // { value: undefined, done: true }
22. What is IIFE (Immediately Invoked Function Expression)?
An IIFE is a function expression that is executed immediately after it's created. It's often used to create a private scope for variables.
(function() {
// Private scope
const message = 'Hello, IIFE!';
console.log(message);
})();
// message is not accessible here
console.log(message); // ReferenceError: message is not defined
Object.create()
and the constructor pattern?
23. What is the difference between Object.create()
creates a new object with the specified prototype object, while the constructor pattern uses a function with the new
keyword to create and initialize objects.
// Object.create()
const personProto = {
greet() {
return `Hello, I'm ${this.name}`;
}
};
const alice = Object.create(personProto);
alice.name = 'Alice';
console.log(alice.greet()); // "Hello, I'm Alice"
// Constructor pattern
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
return `Hello, I'm ${this.name}`;
};
const bob = new Person('Bob');
console.log(bob.greet()); // "Hello, I'm Bob"
24. What is a Symbol?
Symbol is a primitive data type introduced in ES6 that represents a unique identifier. Symbols are often used as property keys to avoid name collisions.
const id = Symbol('id');
const user = {
name: 'Alice',
[id]: 123
};
console.log(user[id]); // 123
console.log(Object.keys(user)); // ['name'] (Symbols are not enumerable)
// Two symbols with the same description are different
const sym1 = Symbol('key');
const sym2 = Symbol('key');
console.log(sym1 === sym2); // false
// Symbol.for creates global symbols
const globalSym1 = Symbol.for('global');
const globalSym2 = Symbol.for('global');
console.log(globalSym1 === globalSym2); // true
25. What are WeakMap and WeakSet?
WeakMap
and WeakSet
are collection objects that hold "weak" references to objects, allowing those objects to be garbage collected if there are no other references to them.
// WeakMap example
let weakMap = new WeakMap();
let obj = {};
weakMap.set(obj, 'associated data');
console.log(weakMap.get(obj)); // 'associated data'
// If obj is set to null and no other references exist,
// the entry in weakMap can be garbage collected
obj = null;
// WeakSet example
let weakSet = new WeakSet();
let obj2 = {};
weakSet.add(obj2);
console.log(weakSet.has(obj2)); // true
26. What is debouncing and throttling?
Debouncing and throttling are techniques to control how many times a function gets executed over time.
// Debouncing: Execute after X ms of inactivity
function debounce(func, delay) {
let timeoutId;
return function(...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
func.apply(this, args);
}, delay);
};
}
// Throttling: Execute at most once every X ms
function throttle(func, limit) {
let inThrottle = false;
return function(...args) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => {
inThrottle = false;
}, limit);
}
};
}
// Usage
const debouncedSearch = debounce(searchFunction, 300);
window.addEventListener('input', debouncedSearch);
const throttledScroll = throttle(scrollHandler, 100);
window.addEventListener('scroll', throttledScroll);
27. What is currying?
Currying is a technique of transforming a function that takes multiple arguments into a sequence of functions that each take a single argument.
// Regular function
function add(a, b, c) {
return a + b + c;
}
// Curried version
function curriedAdd(a) {
return function(b) {
return function(c) {
return a + b + c;
};
};
}
console.log(add(1, 2, 3)); // 6
console.log(curriedAdd(1)(2)(3)); // 6
// With arrow functions
const arrowCurriedAdd = a => b => c => a + b + c;
console.log(arrowCurriedAdd(1)(2)(3)); // 6
28. What is a closure in the context of a loop?
A classic closure issue occurs when creating functions inside a loop that reference the loop variable. Due to closures capturing their environment by reference, all functions created in the loop might share the same reference to the loop variable.
// Problem
function createFunctions() {
const functions = [];
for (var i = 0; i < 3; i++) {
functions.push(function() {
console.log(i);
});
}
return functions;
}
const functions = createFunctions();
functions[0](); // 3 (not 0)
functions[1](); // 3 (not 1)
functions[2](); // 3 (not 2)
// Solution 1: Use let instead of var
function createFunctionsFixed1() {
const functions = [];
for (let i = 0; i < 3; i++) {
functions.push(function() {
console.log(i);
});
}
return functions;
}
// Solution 2: Use an IIFE
function createFunctionsFixed2() {
const functions = [];
for (var i = 0; i < 3; i++) {
functions.push(
(function(value) {
return function() {
console.log(value);
};
})(i)
);
}
return functions;
}
29. What is the Temporal Dead Zone?
The Temporal Dead Zone (TDZ) is the period between entering a scope where a variable is declared with let
or const
and the actual declaration. During this period, accessing the variable results in a ReferenceError
.
{
// Start of TDZ for x
console.log(x); // ReferenceError: Cannot access 'x' before initialization
const x = 10; // End of TDZ for x
}
// TDZ also applies to class declarations
{
const instance = new MyClass(); // ReferenceError: Cannot access 'MyClass' before initialization
class MyClass {}
}
30. What are modules in JavaScript?
Modules are a way to organize code into separate files for better maintainability. ES6 introduced native module support with import
and export
statements.
// math.js
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
export const PI = 3.14159;
// main.js
import { add, subtract, PI } from './math.js';
console.log(add(2, 3)); // 5
// Import everything as a namespace
import * as math from './math.js';
console.log(math.PI); // 3.14159
// Default exports
// utils.js
export default function formatDate(date) {
return date.toISOString().slice(0, 10);
}
// app.js
import formatDate from './utils.js';
console.log(formatDate(new Date())); // "2025-03-09"