Interview Questions

1) What is a closure in JavaScript?


A closure is a function that has access to its own scope, the scope of the outer function, and the global scope. It allows a function to "remember" the environment in which it was created, even after the outer function has finished execution.

Sample Code:

function outer() {
  let outerVariable = 'I am from outer function';

  function inner() {
    console.log(outerVariable); // inner function can access outerVariable
  }

  return inner;
}

const closureExample = outer(); // outer() returns the inner function
closureExample(); // Logs: "I am from outer function"

 

2) What is the difference between var, let, and const?


  • var: Function-scoped, can be re-declared and updated within its scope. It is hoisted but initialized with undefined.
  • let: Block-scoped, can be updated but not re-declared within the same scope.
  • const: Block-scoped, cannot be updated or re-declared once initialized.

Sample Code:

// var example
function varExample() {
  var x = 10;
  if (true) {
    var x = 20; // Re-declared inside block, overwrites the previous value
    console.log(x); // Logs: 20
  }
  console.log(x); // Logs: 20
}
varExample();

// let example
function letExample() {
  let y = 10;
  if (true) {
    let y = 20; // Scoped to block
    console.log(y); // Logs: 20
  }
  console.log(y); // Logs: 10
}
letExample();

// const example
function constExample() {
  const z = 10;
  // z = 20; // This will throw an error because const cannot be reassigned
  console.log(z); // Logs: 10
}
constExample();

 

3) Explain the this keyword in JavaScript.


The value of this in JavaScript depends on how a function is called. It can refer to the global object, the object that called the function, or be bound explicitly using methods like call, apply, or bind.

Sample Code:

// In a regular function
function showThis() {
  console.log(this);
}

showThis(); // In non-strict mode, it logs the global object (window in browsers)

// In an object method
const person = {
  name: 'Alice',
  greet: function() {
    console.log(this.name);
  }
};

person.greet(); // Logs: Alice

// Using `call` to change the context of `this`
function greetPerson() {
  console.log(this.name);
}

const person2 = { name: 'Bob' };
greetPerson.call(person2); // Logs: Bob

 

4) What is event delegation?


Event delegation is a technique in JavaScript where instead of adding event listeners to each child element, a single event listener is added to the parent element. The parent element listens for events on its child elements, which is more efficient.

Sample Code:

// HTML structure
/*
<ul id="list">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>
*/

document.getElementById('list').addEventListener('click', function(e) {
  if (e.target && e.target.nodeName === 'LI') {
    console.log(`You clicked on ${e.target.textContent}`);
  }
});

 

5) What is the difference between null and undefined?


  • null: Represents the intentional absence of any value. It is an object in JavaScript.
  • undefined: Indicates that a variable has been declared but has not yet been assigned a value.

Sample Code:

let a;
console.log(a); // Logs: undefined (a is declared but not assigned)

let b = null;
console.log(b); // Logs: null (null is explicitly assigned to b)

 

6) What are promises in JavaScript?


A Promise is an object representing the eventual completion (or failure) of an asynchronous operation and its resulting value. Promises can be in three states: pending, fulfilled, or rejected.

Sample Code:

function examplePromise() {
  return new Promise((resolve, reject) => {
    const success = true;

    if (success) {
      resolve('Operation successful');
    } else {
      reject('Operation failed');
    }
  });
}

examplePromise()
  .then((message) => {
    console.log(message); // Logs: "Operation successful"
  })
  .catch((error) => {
    console.log(error);
  });

 

7) What are arrow functions in JavaScript?


Arrow functions provide a shorter syntax for writing functions. They do not have their own this value and inherit this from the surrounding context.

Sample Code:

// Traditional function
const traditionalFunction = function() {
  console.log(this);
};

// Arrow function
const arrowFunction = () => {
  console.log(this); // Inherits `this` from the surrounding context
};

traditionalFunction(); // Logs: global object (or undefined in strict mode)
arrowFunction(); // Logs: inherited `this`

 

8) Explain how setTimeout works in JavaScript.


setTimeout is a method that executes a function after a specified delay (in milliseconds).

Sample Code:

console.log('Start');

setTimeout(function() {
  console.log('This runs after 2 seconds');
}, 2000); // 2000ms = 2 seconds

console.log('End');
// Output:
// Start
// End
// This runs after 2 seconds

 

9) What is the difference between == and === in JavaScript?


  • == (loose equality) compares values for equality after type coercion.
  • === (strict equality) compares both the values and the types without coercion.

Sample Code:

console.log(5 == '5');  // Logs: true (due to type coercion)
console.log(5 === '5'); // Logs: false (different types)

let obj1 = {name: 'Alice'};
let obj2 = {name: 'Alice'};
console.log(obj1 == obj2);  // Logs: false (different object references)
console.log(obj1 === obj2); // Logs: false (different object references)

 

10) What is the use of bind() in JavaScript?


bind() is used to create a new function that, when called, has its this value set to a specific object, with a given sequence of arguments.

Sample Code:

function greet() {
  console.log(`Hello, ${this.name}`);
}

const person = { name: 'Charlie' };

const greetPerson = greet.bind(person);
greetPerson(); // Logs: Hello, Charlie

 

11) What are higher-order functions in JavaScript?


A higher-order function is a function that either takes one or more functions as arguments or returns a function as its result.

Sample Code:

// Function that accepts another function as an argument
function greetPerson(name, greetFunction) {
  console.log(greetFunction(name));
}

function sayHello(name) {
  return `Hello, ${name}!`;
}

greetPerson('Alice', sayHello); // Logs: Hello, Alice!

// Function that returns another function
function multiplier(factor) {
  return function(number) {
    return number * factor;
  };
}

const double = multiplier(2);
console.log(double(5)); // Logs: 10

 

12) What is setInterval and how does it work in JavaScript?


setInterval() is used to repeatedly execute a function at a specified interval in milliseconds.

Sample Code:

let count = 0;
const intervalId = setInterval(() => {
  count++;
  console.log(count); // Logs 1, 2, 3, ..., every second
  if (count === 5) {
    clearInterval(intervalId); // Stops the interval after 5 iterations
  }
}, 1000);

 

13) What is the bind() method, and how is it different from call() and apply()?


  • bind(): Creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments.
  • call(): Immediately invokes the function and sets the this value to the provided object, followed by the arguments.
  • apply(): Similar to call(), but arguments are passed as an array.

Sample Code:

function greet(message) {
  console.log(`${message}, ${this.name}`);
}

const person = { name: 'Bob' };

const boundGreet = greet.bind(person);
boundGreet('Hello'); // Logs: Hello, Bob

greet.call(person, 'Hi'); // Logs: Hi, Bob
greet.apply(person, ['Good morning']); // Logs: Good morning, Bob

 

14) What are async/await in JavaScript?


async and await provide a more readable and straightforward way to work with asynchronous code. The async keyword is used to declare a function that returns a promise, and await is used to wait for a promise to resolve or reject inside an async function.

Sample Code:

function fetchData() {
  return new Promise((resolve) => {
    setTimeout(() => resolve('Data fetched!'), 2000);
  });
}

async function getData() {
  console.log('Fetching...');
  const result = await fetchData(); // Waits for fetchData to resolve
  console.log(result); // Logs: Data fetched!
}

getData();

 

15) Explain the difference between slice() and splice() methods.


  • slice(): Returns a shallow copy of a portion of an array or string without modifying the original.
  • splice(): Changes the contents of an array by removing or replacing existing elements and/or adding new elements in place.

Sample Code:

// slice example
const array1 = [1, 2, 3, 4, 5];
const slicedArray = array1.slice(1, 3); // Returns a new array [2, 3]
console.log(slicedArray); // Logs: [2, 3]

// splice example
const array2 = [1, 2, 3, 4, 5];
array2.splice(2, 2, 'a', 'b'); // Removes 2 elements starting from index 2 and adds 'a' and 'b'
console.log(array2); // Logs: [1, 2, 'a', 'b', 5]

 

16) What is the difference between Object.freeze() and Object.seal()?


  • Object.freeze(): Makes an object immutable. Properties cannot be added, removed, or modified.
  • Object.seal(): Prevents properties from being added or removed, but existing properties can still be modified.

Sample Code:

const obj = { name: 'John', age: 30 };

// Using Object.freeze
Object.freeze(obj);
obj.age = 31; // Won't work because the object is frozen
console.log(obj.age); // Logs: 30

// Using Object.seal
const obj2 = { name: 'Alice', age: 25 };
Object.seal(obj2);
obj2.age = 26; // This works because the properties can be modified
obj2.city = 'NY'; // Won't work because new properties can't be added
console.log(obj2); // Logs: { name: 'Alice', age: 26 }

 

17) Explain destructuring in JavaScript.


Destructuring allows unpacking values from arrays or objects into distinct variables in a concise syntax.

Sample Code:

// Array destructuring
const numbers = [10, 20, 30];
const [a, b, c] = numbers;
console.log(a, b, c); // Logs: 10 20 30

// Object destructuring
const person = { name: 'Charlie', age: 35 };
const { name, age } = person;
console.log(name, age); // Logs: Charlie 35

// Nested destructuring
const user = { profile: { name: 'Dave', city: 'Berlin' } };
const { profile: { name: userName, city } } = user;
console.log(userName, city); // Logs: Dave Berlin

 

18) What is a JavaScript module?


A module is a way to organize JavaScript code by breaking it into separate files, allowing specific functions or variables to be imported and exported between files. Modules help in better code maintainability.

Sample Code (using ES6 syntax):

// math.js (module)
export function add(a, b) {
  return a + b;
}

// app.js
import { add } from './math.js';
console.log(add(2, 3)); // Logs: 5

 

19) What is the event loop in JavaScript?


The event loop is the mechanism in JavaScript that handles asynchronous code execution. It continuously checks the call stack and the task queue to process tasks (like function calls or events). If the stack is empty, it moves tasks from the task queue to the call stack.

Sample Code:

console.log('Start');

setTimeout(() => {
  console.log('Middle');
}, 0);

console.log('End');

// Output:
// Start
// End
// Middle

 

20) What is the localStorage and sessionStorage in JavaScript?


  • localStorage: Stores data with no expiration time. Data remains even after the browser is closed.
  • sessionStorage: Stores data for the duration of the page session. Data is cleared when the page session ends (i.e., when the browser or tab is closed).

Sample Code:

// Using localStorage
localStorage.setItem('name', 'Alice');
console.log(localStorage.getItem('name')); // Logs: Alice

// Using sessionStorage
sessionStorage.setItem('sessionName', 'Bob');
console.log(sessionStorage.getItem('sessionName')); // Logs: Bob

 

21) What is the this keyword in arrow functions?


In arrow functions, this does not refer to the object that calls the function, but instead, it inherits the this value from the surrounding context (lexical scoping).

Sample Code:

const person = {
  name: 'Alice',
  greet: function() {
    setTimeout(() => {
      console.log(`Hello, ${this.name}`); // Arrow function uses lexical scoping
    }, 1000);
  }
};

person.greet(); // Logs: Hello, Alice

If we had used a regular function inside setTimeout, this would refer to the global object, and the name property would be undefined.

22) What is the difference between Array.prototype.map() and Array.prototype.forEach()?


  • map(): Returns a new array with the results of calling a provided function on every element of the array.
  • forEach(): Executes a provided function once for each element in the array but does not return anything (undefined).

Sample Code:

// map example
const numbers = [1, 2, 3];
const doubled = numbers.map(num => num * 2);
console.log(doubled); // Logs: [2, 4, 6]

// forEach example
const numbers2 = [1, 2, 3];
numbers2.forEach(num => console.log(num * 2)); 
// Logs: 2
// Logs: 4
// Logs: 6

 

23) What is the difference between setTimeout() and setImmediate()?


  • setTimeout(): Executes a function after a specified delay (in milliseconds).
  • setImmediate(): Executes a function immediately after the current event loop cycle (next iteration).

Sample Code:

setTimeout(() => {
  console.log('setTimeout');
}, 0);

setImmediate(() => {
  console.log('setImmediate');
});

// Logs:
// setImmediate
// setTimeout

 

24) What are JavaScript generators?


Generators are special functions that can be paused and resumed, allowing for more control over function execution. They are defined using function* syntax and use the yield keyword to pause and return a value.

Sample Code:

function* generateNumbers() {
  yield 1;
  yield 2;
  yield 3;
}

const generator = generateNumbers();
console.log(generator.next().value); // Logs: 1
console.log(generator.next().value); // Logs: 2
console.log(generator.next().value); // Logs: 3
console.log(generator.next().value); // Logs: undefined

 

25) What is the Proxy object in JavaScript?


A Proxy object enables the creation of custom behavior for fundamental operations (such as property lookup, assignment, etc.) on an object. You can define traps (handlers) to intercept and redefine operations like get, set, etc.

Sample Code:

const person = {
  name: 'Alice',
  age: 30
};

const handler = {
  get(target, prop) {
    if (prop in target) {
      return `Property ${prop} is ${target[prop]}`;
    }
    return `Property ${prop} does not exist`;
  }
};

const proxyPerson = new Proxy(person, handler);

console.log(proxyPerson.name);  // Logs: Property name is Alice
console.log(proxyPerson.age);   // Logs: Property age is 30
console.log(proxyPerson.city);  // Logs: Property city does not exist

 

26) What is set and map in JavaScript?


  • Set: A collection of unique values, where no duplicate values are allowed.
  • Map: A collection of key-value pairs where keys can be of any data type, and each key is unique.

Sample Code:

// Set example
const uniqueNumbers = new Set([1, 2, 3, 3, 4, 5, 5]);
console.log(uniqueNumbers); // Logs: Set { 1, 2, 3, 4, 5 }

// Map example
const map = new Map();
map.set('name', 'Alice');
map.set('age', 30);
console.log(map.get('name')); // Logs: Alice
console.log(map.get('age'));  // Logs: 30

 

27) Explain the concept of promises chaining in JavaScript.


Promises chaining allows multiple then() or catch() methods to be linked together to perform sequential asynchronous operations. Each then() method returns a new promise, allowing further chaining.

Sample Code:

function fetchData() {
  return new Promise((resolve) => {
    setTimeout(() => resolve('Data fetched!'), 1000);
  });
}

fetchData()
  .then((result) => {
    console.log(result); // Logs: Data fetched!
    return 'Processing data...';
  })
  .then((message) => {
    console.log(message); // Logs: Processing data...
    return 'Finished processing';
  })
  .then((message) => {
    console.log(message); // Logs: Finished processing
  })
  .catch((error) => {
    console.log('Error:', error);
  });

 

28) What are WeakMap and WeakSet in JavaScript?


  • WeakMap: A collection of key-value pairs where the keys must be objects, and the values can be any data type. The keys are weakly referenced, meaning they are garbage-collected if there are no other references to them.
  • WeakSet: A collection of unique objects where the objects are weakly referenced and can be garbage-collected when there are no other references to them.

Sample Code:

// WeakMap example
let obj1 = {};
let weakMap = new WeakMap();
weakMap.set(obj1, 'value');

console.log(weakMap.get(obj1)); // Logs: value

obj1 = null; // obj1 is now eligible for garbage collection

// WeakSet example
let obj2 = {};
let weakSet = new WeakSet();
weakSet.add(obj2);

console.log(weakSet.has(obj2)); // Logs: true

obj2 = null; // obj2 is eligible for garbage collection

 

29) What is the spread operator in JavaScript?


The spread operator (...) allows you to unpack elements from an array or object. It is useful for copying or merging data.

Sample Code:

// Spread in arrays
const numbers = [1, 2, 3];
const moreNumbers = [...numbers, 4, 5];
console.log(moreNumbers); // Logs: [1, 2, 3, 4, 5]

// Spread in objects
const person = { name: 'Alice', age: 30 };
const newPerson = { ...person, city: 'New York' };
console.log(newPerson); // Logs: { name: 'Alice', age: 30, city: 'New York' }

 

30) What is the difference between slice() and splice() in JavaScript?


  • slice(): Returns a shallow copy of a portion of an array (or string) without modifying the original array.
  • splice(): Changes the contents of an array by removing, replacing, or adding elements in place.

Sample Code:

// slice example
const arr1 = [1, 2, 3, 4, 5];
const slicedArr = arr1.slice(1, 3); // Returns [2, 3]
console.log(slicedArr); // Logs: [2, 3]

// splice example
const arr2 = [1, 2, 3, 4, 5];
arr2.splice(2, 2, 'a', 'b'); // Removes 2 elements starting at index 2 and adds 'a' and 'b'
console.log(arr2); // Logs: [1, 2, 'a', 'b', 5]

 

31) What is a Set in JavaScript?


A Set is a collection of unique values. It can store any type of data, and it automatically removes duplicate values.

Sample Code:

const mySet = new Set();
mySet.add(1);
mySet.add(2);
mySet.add(3);
mySet.add(2); // Duplicate value, won't be added

console.log(mySet); // Logs: Set { 1, 2, 3 }

 

32) What is the difference between arguments and rest parameters in JavaScript?


  • arguments: An array-like object that contains all the arguments passed to a function (except in arrow functions).
  • rest parameters: A syntax that allows us to represent an indefinite number of arguments as an array. It is used in the function definition.

Sample Code:

// Using arguments (works with traditional functions only)
function sum() {
  let total = 0;
  for (let i = 0; i < arguments.length; i++) {
    total += arguments[i];
  }
  return total;
}
console.log(sum(1, 2, 3)); // Logs: 6

// Using rest parameters
function sumRest(...numbers) {
  return numbers.reduce((total, num) => total + num, 0);
}
console.log(sumRest(1, 2, 3)); // Logs: 6

 

33) What is the purpose of eval() in JavaScript, and why should it be avoided?


eval() is a function that evaluates a string of JavaScript code and executes it. However, it can pose serious security risks (like code injection attacks) and should generally be avoided.

Sample Code:

const result = eval("2 + 2");
console.log(result); // Logs: 4

// Potential danger example
const userInput = "alert('You have been hacked!')";
eval(userInput); // This could execute malicious code if the input is controlled by the user.

 

34) What are the differences between process.nextTick() and setImmediate()?


  • process.nextTick(): Runs a callback after the current operation completes and before any I/O tasks. It's part of Node.js and used for high-priority callbacks.
  • setImmediate(): Executes the callback after the current event loop cycle, but after any I/O tasks.

Sample Code:

console.log('Start');

// process.nextTick example
process.nextTick(() => {
  console.log('nextTick callback');
});

// setImmediate example
setImmediate(() => {
  console.log('setImmediate callback');
});

console.log('End');

// Logs:
// Start
// End
// nextTick callback
// setImmediate callback

 

35) What are the differences between synchronous and asynchronous functions in JavaScript?


  • Synchronous functions: Execute code in a blocking manner, meaning the next line of code doesn't run until the current one completes.
  • Asynchronous functions: Execute code in a non-blocking manner, meaning the next line of code can run while the asynchronous operation is being executed.

Sample Code:

// Synchronous function
function syncFunction() {
  console.log('Start');
  console.log('End');
}
syncFunction(); 
// Logs: 
// Start
// End

// Asynchronous function
function asyncFunction() {
  console.log('Start');
  setTimeout(() => {
    console.log('Inside setTimeout');
  }, 1000);
  console.log('End');
}
asyncFunction();
// Logs:
// Start
// End
// Inside setTimeout

 

36) What is the purpose of Symbol in JavaScript?


A Symbol is a primitive data type introduced in ES6 that is used to create unique identifiers for object properties. Each Symbol is unique, ensuring that no property name conflicts occur.

Sample Code:

const mySymbol = Symbol('description');
const obj = {
  [mySymbol]: 'value'
};

console.log(obj[mySymbol]); // Logs: value
console.log(mySymbol); // Logs: Symbol(description)

 

37) What is Event Bubbling and Event Capturing?


  • Event Bubbling: The event starts from the target element and propagates up to the root of the document.
  • Event Capturing: The event starts from the root of the document and propagates down to the target element.

By default, JavaScript uses event bubbling, but we can specify event capturing by passing true to addEventListener().

Sample Code:

document.getElementById('child').addEventListener('click', () => {
  console.log('Child clicked');
}, false); // Bubbling phase

document.getElementById('parent').addEventListener('click', () => {
  console.log('Parent clicked');
}, true); // Capturing phase

 

38) What is Array.prototype.reduce() in JavaScript?


The reduce() method executes a reducer function (that you provide) on each element of the array (from left to right) and reduces the array to a single value.

Sample Code:

const numbers = [1, 2, 3, 4];

const sum = numbers.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
console.log(sum); // Logs: 10

const product = numbers.reduce((accumulator, currentValue) => accumulator * currentValue, 1);
console.log(product); // Logs: 24

 

39) What is destructuring and how does it work with objects and arrays?


Destructuring allows you to extract values from arrays or objects and assign them to variables in a concise syntax.

Sample Code:

// Array Destructuring
const arr = [10, 20, 30];
const [a, b] = arr;
console.log(a, b); // Logs: 10 20

// Object Destructuring
const person = { name: 'John', age: 25 };
const { name, age } = person;
console.log(name, age); // Logs: John 25

 

40) What is the new keyword in JavaScript?


The new keyword is used to create a new instance of an object that has a constructor function. It sets the context of this inside the constructor function to the newly created object.

Sample Code:

function Person(name, age) {
  this.name = name;
  this.age = age;
}

const person1 = new Person('Alice', 30);
console.log(person1); // Logs: Person { name: 'Alice', age: 30 }

 

41) What is the difference between call(), apply(), and bind() methods in JavaScript?


  • call(): Immediately invokes the function with a given this context and arguments passed individually.
  • apply(): Similar to call(), but the arguments are passed as an array.
  • bind(): Returns a new function with the this context set to the specified value, and optional arguments.

Sample Code:

function greet(city) {
  console.log(`${this.name} lives in ${city}`);
}

const person = { name: 'Alice' };

greet.call(person, 'Paris');  // Logs: Alice lives in Paris
greet.apply(person, ['London']);  // Logs: Alice lives in London

const boundGreet = greet.bind(person);
boundGreet('New York');  // Logs: Alice lives in New York

 

42) Find the Longest Substring Without Repeating Characters


function longestUniqueSubstring(str) {
  let maxLength = 0;
  let start = 0;
  const charMap = {};

  for (let end = 0; end < str.length; end++) {
    const char = str[end];
    
    if (charMap[char] !== undefined && charMap[char] >= start) {
      start = charMap[char] + 1;
    }
    
    charMap[char] = end;
    maxLength = Math.max(maxLength, end - start + 1);
  }

  return maxLength;
}

// Example usage:
console.log(longestUniqueSubstring('abcabcbb'));  // Output: 3 (abc)

Explanation:

  • We use a sliding window technique with two pointers (start and end) to track the substring. We store the last index of each character in charMap. When a duplicate character is found, we update the start pointer to the position after the last occurrence of the character.