DEV Community

Cover image for Most asked JavaScript Interview Questions🚀
bugudiramu
bugudiramu

Posted on • Edited on

Most asked JavaScript Interview Questions🚀

Introduction 🌐

Welcome to the Most asked JavaScript Interview Questions guide, your ultimate prep tool for mastering JavaScript interviews! 🚀 From the fundamentals to advanced concepts, we've got you covered. Let's get started!

I've dedicated significant effort to curating this extensive content list. Show your support by following, liking, and subscribing to stay updated on new articles. Feel free to share your questions or suggestions in the comments—I'll make sure to respond to most messages. Your engagement is highly appreciated!


Explain Event Delegation

Event Delegation, It is rooted in the concept of Event Bubbling, streamlines event handling by allowing you to manage events at a higher level in the DOM tree rather than directly where the event originated.

What does this mean?

In simple terms, when you interact with an element (e.g., clicking a button), the event ripples up the DOM tree from the target element to its parent elements. This pattern simplifies event management and is demonstrated in the following HTML and JavaScript example:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Event Delegation Example</title>
  </head>
  <body>
    <div>
      <h1>
        <button>Click Here</button>
      </h1>
    </div>

    <script>
      // Wait for the DOM to be fully loaded
      document.addEventListener("DOMContentLoaded", function () {
        // Add a click event listener to the entire document
        document.addEventListener("click", function (event) {
          // Identify the clicked element
          const targetElement = event.target;
          console.log("Clicked on:", targetElement.tagName);

          // Check if the clicked element is a button
          if (targetElement.tagName === "BUTTON") {
            alert("Button Clicked!");
          }
        });
      });
    </script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Explain how this works in JavaScript. Can you give an example of one of the ways that working with this has changed in ES6?

  • this refers to the current execution context.
  • In ES6, arrow functions don't have their own this, so they inherit it from the surrounding scope, providing a more predictable behavior.
/****** ES5 example with a regular function ******/
function printValueFunc() {
  this.value = 42;

  // Within this function, 'this' refers to the function's context
  setTimeout(function () {
    console.log(this.value); // undefined
  }, 1000);
}

printValueFunc();

/****** ES6 example with an arrow function *******/
function printValueArrowFunc() {
  this.value = 42;

  // Arrow functions inherit 'this' from the surrounding scope
  setTimeout(() => {
    console.log(this.value); // 42
  }, 1000);
}

printValueArrowFunc();
Enter fullscreen mode Exit fullscreen mode

Explain how prototypal inheritance works?

  • In JavaScript, objects can inherit stuff (like properties and methods) from other objects through a thing called the "prototype chain." Here's the deal: when an object can't find something it needs (like a property or method), JavaScript checks the chain of objects until it finds what it's looking for or hits the end. Simple, right?

Example:

// Parent object
const person = {
  name: undefined,
  printName() {
    console.log(this.name);
  },
};

// Child object inheriting from the parent
const user = Object.create(person);
user.name = "Ramu";

user.printName(); // Outputs: Ramu
Enter fullscreen mode Exit fullscreen mode

What is the difference between a variable that is: null, undefined, or undeclared? How would you go about checking for any of these states?

  • Null: Assigned intentionally to signify no value or object.
  • Undefined: Default value for uninitialized variables.
  • Undeclared: Variables not formally declared in the code.

  • For null or undefined, use explicit checks.

  • For undeclared, employ a try-catch block or the typeof operator.

let varNull = null;
let varUndefined;
// let varUndeclared; // Uncommenting this line would make it undeclared

// Check for null
if (varNull === null) {
  console.log("Variable is null");
}

// Check for undefined
if (varUndefined === undefined) {
  console.log("Variable is undefined");
}

// Check for undeclared (using try-catch)
try {
  if (typeof varUndeclared === "undefined") {
    console.log("Variable is undeclared");
  }
} catch (error) {
  console.log("Variable is undeclared");
}
Enter fullscreen mode Exit fullscreen mode

What is a closure, and how/why would you use one?

A closure is a combination of a function and the environment in which it was created. It allows a function to access variables from its outer scope even after the outer function has finished executing.

How/why would you use a closure?

Closures are useful for creating private variables, maintaining state, and implementing data encapsulation in JavaScript. They enable functions to "remember" and access variables from their lexical scope, providing a way to achieve encapsulation and data hiding.

Example:

function createCounter() {
  let count = 0;

  function increment() {
    count++;
    console.log(count);
  }

  function decrement() {
    count--;
    console.log(count);
  }

  return { increment, decrement };
}

const counter = createCounter();
counter.increment(); // Output: 1
counter.increment(); // Output: 2
counter.decrement(); // Output: 1
Enter fullscreen mode Exit fullscreen mode

In this example, the createCounter function returns an object with increment and decrement functions. The count variable is accessible only through these functions, demonstrating the concept of closures for maintaining private state.

What language constructions do you use for iterating over object properties and array items?

  • To iterate over arrays, you can use loops like for or methods like forEach and map. For objects, you can use a for...in loop or the Object.keys() method.

Example:

const numbers = [1, 2, 3, 4, 5];
numbers.forEach((number) => {
  console.log(number);
});

const person = { name: "Ramu", age: 24, job: "Full Stack Developer" };
for (const key in person) {
  console.log(`${key}: ${person[key]}`);
}
Enter fullscreen mode Exit fullscreen mode

Can you describe the main difference between the Array.forEach() loop and Array.map() methods and why you would pick one versus the other?

  • The forEach method is employed to go through each element in an array, but it doesn't create a new array. Instead, it's used for performing actions on each element, and it can mutate the original array.

  • On the other hand, the map method is utilized to alter array elements and generate a new array. Specifically, map produces a new array by applying a given function to every element and ensures that the original array remains unchanged.

Example:

const numbers = [1, 2, 3, 4];
numbers.forEach((num, idx, array) => {
  console.log(num);
  array[idx] = num * 2; // Mutating the original array
});

console.log(numbers); // Original array is mutated

const doubledNumbers = numbers.map((num) => num * 2); // Returns new array
console.log(doubledNumbers);
Enter fullscreen mode Exit fullscreen mode

What is a typical use case for anonymous functions?

  • People often use anonymous functions for short or one-time tasks, such as passing a function as an argument or defining functions within a code block.

Example:

const numbers = [1, 2, 3, 4, 5];
const squared = numbers.map(function (x) {
  return x * x;
});
Enter fullscreen mode Exit fullscreen mode

What is the difference between host objects and native objects?

  • Native objects are part of the JavaScript language (e.g., Array, Object), while host objects are provided by the environment (e.g., window, document object in browsers).

Explain the difference between function foo() {} and var foo = function() {}:

  • Function Declaration (function foo() {}):

    • Declares a function named foo.
    • Can be used before the declaration due to hoisting.
  • Function Expression (var foo = function() {}):

    • Assigns an anonymous function to the variable foo.
    • Must be declared before use, or it will result in an error.

Example:

// Function Expression
console.log(foo()); // Error: Cannot access 'foo' before initialization

const foo = function () {
  return "Hello from foo...";
};

console.log(foo());

// Function Declaration
function foo() {
  return "Hello from foo...";
}
Enter fullscreen mode Exit fullscreen mode

Can you explain what Function.call and Function.apply do? What is the notable difference between the two?

  • Both methods are used to invoke a function with a specific this value. The difference is in how arguments are passed - call takes arguments individually, while apply takes an array of arguments.

Example:

function concatenate(s1, s2) {
  return s1 + s2;
}

console.log(concatenate.call(null, "Hello", " World"));
console.log(concatenate.apply(null, ["Hello", " World"]));
Enter fullscreen mode Exit fullscreen mode

Explain Function.prototype.bind.

  • bind creates a new function with a specified this value and initial arguments. It doesn't invoke the function immediately but returns a new function that can be executed later.

Example:

const person = {
  name: "Ramu",
  greet: function () {
    console.log(`Hello, ${this.name}!`);
  },
};

const boundGreet = person.greet.bind(person);

boundGreet(); // Outputs: Hello, Ramu!
Enter fullscreen mode Exit fullscreen mode

Explain Feature Detection, Feature Inference, and UA String Usage

  • Feature Detection: Checks if a browser supports a specific feature.

  • Feature Inference: Assumes support for a feature based on the presence of other supported features.

  • UA String Usage: Utilizes the User Agent (UA) string, but it's unreliable as it can be manipulated.

Explain "hoisting".

  • Hoisting is a behavior in JavaScript where variable and function declarations are moved to the top of their containing scope during the compilation phase.

Example:

console.log(foo());

function foo() {
  return "Hello from foo...";
}
Enter fullscreen mode Exit fullscreen mode

What is type coercion? What are common pitfalls of relying on type coercion in JavaScript code?

  • Type coercion is the automatic conversion of values from one type to another. Pitfalls include unexpected coercion results, potential loss of precision, and difficulty in debugging.

Example:

const num = 5;
const str = "10";

const output = num + str;

console.log(output); // Outputs "510" due to type coercion, concatenating the number and string.
Enter fullscreen mode Exit fullscreen mode

What is event bubbling?

  • Event bubbling is the order in which events propagate through the DOM hierarchy from the target element to the root.

  • For a more in-depth understanding, explore examples at Event Capturing vs Event Bubbling.

What is event capturing?

  • Event capturing is the opposite of bubbling, where events are captured from the root to the target element.

  • For a more in-depth understanding, explore examples at Event Capturing vs Event Bubbling.

What is the difference between an "attribute" and a "property"?

  • An attribute is a value in HTML markup, while a property is a value in the DOM. Changing a property can affect the corresponding attribute and vice versa.

Example:

<!-- HTML Markup -->
<input type="text" value="example" id="myInput" />

<!-- JavaScript manipulating the corresponding property in the DOM -->
<script>
  document.getElementById("myInput").value = "updatedValue";
</script>
Enter fullscreen mode Exit fullscreen mode

In the above example, the value attribute in HTML corresponds to the value property in the DOM, showcasing their connection

What are the pros and cons of extending built-in JavaScript objects?

  • Pros: Can add functionality globally.
  • Cons: May lead to naming conflicts, break existing code, or cause unexpected behavior.

Example:

// Extending Array prototype to sum all elements
Array.prototype.sum = function () {
  return this.reduce((acc, val) => acc + val, 0);
};

const numbers = [1, 2, 3, 4, 5];
console.log(numbers.sum()); // Output: 15
Enter fullscreen mode Exit fullscreen mode

What's the distinction between == and === in JavaScript?

In JavaScript, == performs type coercion, meaning it converts the operands to the same type before making the comparison. On the other hand, === strictly checks both value and type equality without any conversion.

Example:

const a = 2;
const b = "2";
console.log(a == b); // true (type coercion)
console.log(a === b); // false (strict equality)
Enter fullscreen mode Exit fullscreen mode

In the example, == evaluates to true because it coerces the string "2" to a number before comparison, while === evaluates to false as it checks both value and type, and the types are different.

Explain the same-origin policy with regards to JavaScript.

  • Same-origin policy restricts web pages from making requests to a different domain than the one that served the web page.

Why is it called a Ternary operator, and what does the word "Ternary" indicate?

  • It's called the ternary operator because it takes three operands. It's the only JavaScript operator that takes three operands.

Example

function isEven(number) {
  return number % 2 === 0;
}
const result = isEven(2) ? "EVEN" : "ODD";
console.log(result); // EVEN
Enter fullscreen mode Exit fullscreen mode

What is strict mode? What are some of the advantages/disadvantages of using it?

  • Strict mode is a way to catch common coding errors and prevent the use of certain error-prone features. It makes debugging easier but might break existing code that relies on non-strict behavior.

What tools and techniques do you use for debugging JavaScript code?

I use various tools and techniques for debugging JavaScript code, such as browser developer tools, console.log, the debugger statement, and third-party tools like the VS Code debugger.

Example:

function calculateSum(a, b) {
  console.log("Calculating sum...");
  debugger;
  const sum = a + b;
  console.log(`The sum of ${a} and ${b} is ${sum}`);
  return sum;
}

calculateSum(3, 5);
Enter fullscreen mode Exit fullscreen mode

In this example, I've used console.log to log messages during the calculation and the debugger statement to pause execution and inspect variables using browser developer tools.

Explain the difference between mutable and immutable objects.

Mutable objects are changeable, allowing modifications after creation. In contrast, immutable objects, once created, cannot be altered.

Example:

// Mutable - can be changed
let str = "hello world";
str = "hello world again";
console.log(str); // hello world again

// Immutable - cannot be directly altered
str[0] = "H";
console.log(str); // hello world again
Enter fullscreen mode Exit fullscreen mode

Primitive Values vs. Non-Primitive Values

  • Primitive values are immutable:

    • Example: let str1 = "hello world";
    • Attempting direct alteration, like str1[0] = "H";, won't work.
  • Primitive values are compared by value:

    • Example: let str1 = "hello world";
    • Comparing two identical primitive values with === yields true.
  • Non-primitive values are mutable:

    • Example: const arr1 = [1, 2, 3, 4, 5];
    • Arrays and objects can be modified after creation.
  • Non-primitive values are compared by reference, not value:

    • Example:
    const arr1 = [1, 2, 3, 4, 5];
    const arr2 = [1, 2, 3, 4, 5];
    console.log(arr1 === arr2); // false
    
    const obj1 = { key: "name", value: "ramu" };
    const obj2 = { key: "name", value: "ramu" };
    console.log(obj1 === obj2); // false
    
    const arr3 = arr1;
    const obj3 = obj1;
    console.log(arr3 === arr1); // true
    console.log(obj3 === obj1); // true
    

What is an example of an immutable object in JavaScript?

  • All primitive types are immutable. Once created, their values cannot be changed.

Example:

// Mutable - can be changed
let str = "hello world";
str = "hello world again";
console.log(str); // hello world again

// Immutable - cannot be directly altered
str[0] = "H";
console.log(str); // hello world again
Enter fullscreen mode Exit fullscreen mode

What are the pros and cons of immutability?

  • Pros: Include simpler code, easier debugging, and improved concurrency.
  • Cons: include potentially higher memory usage and the need to create new objects for every change.

How can you achieve immutability in your own code?

  • Use methods like Object.assign, spread syntax, or libraries like Immutable.js to create new objects instead of modifying existing ones.
const mutableObject = { count: 5, value: "example" };

const immutableObject = { ...mutableObject, count: 6 };

console.log({ mutableObject, immutableObject });
Enter fullscreen mode Exit fullscreen mode

Explain the difference between synchronous and asynchronous functions.

Synchronous functions run one after another, pausing the program until each completes. Asynchronous functions enable the program to keep going while waiting for an operation to finish.

Example:

function synchronousTask() {
  console.log("Task 1");
  console.log("Task 2");
}

synchronousTask();
console.log("Task 3");
Enter fullscreen mode Exit fullscreen mode
function asynchronousTask() {
  console.log("Task 1");
  setTimeout(() => {
    console.log("Task 2");
  }, 1000);
}

asynchronousTask();
console.log("Next Task");
Enter fullscreen mode Exit fullscreen mode

In the synchronous example, each task runs sequentially, pausing the program. In the asynchronous example, the program continues executing while waiting for the setTimeout operation to finish.

What is the event loop? What is the difference between call stack and task queue?

  • The event loop is how JavaScript handles asynchronous code, ensuring it runs smoothly without blocking. The call stack processes synchronous code, while the task queue holds asynchronous events to be executed.

  • For visual demo visit Event Loop

What are the differences between variables created using let, var, or const?

Understanding the Var, Let, and Const Keywords in JavaScript

In JavaScript, the keywords var, let, and const are used to declare variables, but they behave differently in terms of scope and reassignment.

  1. var: Variables declared with var have function scope. This means they are only accessible within the function where they are defined.

  2. let: Variables declared with let have block scope. They are accessible within the block (enclosed by curly braces) where they are defined.

  3. const: Similar to let, variables declared with const also have block scope. However, once a value is assigned to a const variable, it cannot be reassigned.

Example:

function exampleVar() {
  if (true) {
    var x = 10;
  }
  console.log(x); // Outputs 10
}

function exampleLet() {
  if (true) {
    let y = 20;
  }
  console.log(y); // Error: y is not defined
}

function exampleConst() {
  const z = 30;
  z = 40; // Error: Assignment to constant variable
}
Enter fullscreen mode Exit fullscreen mode

In the examples, var and let exhibit different scoping behavior, and const prevents reassignment after the initial value is set.

What are the differences between ES6 class and ES5 function constructors?

  • ES6 classes provide a cleaner syntax for creating constructor functions and prototypes, making it more similar to classical inheritance.

Example

// ES5 Function Constructor
function PersonES5(name, age) {
  this.name = name;
  this.age = age;
}

PersonES5.prototype.greet = function () {
  console.log("Hello, I'm " + this.name);
};

// ES6 Class
class PersonES6 {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  greet() {
    console.log(`Hello, I'm ${this.name}`);
  }
}
Enter fullscreen mode Exit fullscreen mode

Can you offer a use case for the new arrow => function syntax? How does this new syntax differ from other functions?

  • Arrow functions are handy for short, concise tasks and have lexical scoping. They lack their own this and bind it lexically, which can be advantageous in specific scenarios.

Example:

// Traditional/Normal Function
function add(a, b) {
  return a + b;
}

// Arrow Function
const addArrow = (a, b) => a + b;
Enter fullscreen mode Exit fullscreen mode

What advantage is there for using the arrow syntax for a method in a constructor?

  • Arrow syntax prevents the creation of a new this binding, ensuring the method shares the this value of the enclosing scope.

What is the definition of a higher-order function?

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

Example

const cube = (x) => Math.pow(x, 3);

function higherOrderFunc(n, func) {
  return func(n);
}

console.log(higherOrderFunc(3, cube));
Enter fullscreen mode Exit fullscreen mode

Can you give an example for destructuring an object or an array?

  • Destructuring allows you to extract values from objects or arrays and assign them to variables in a concise way. Example:
const person = { name: "Ramu", age: 30 };
const { name, age } = person; // { name: "Ramu", age: 30 }

const numbers = [1, 2, 3, 4, 5];
const [first, second, ...rest] = numbers; // { first: 1, second: 2, rest: [ 3, 4, 5 ] }
Enter fullscreen mode Exit fullscreen mode

Can you give an example of generating a string with ES6 Template Literals?

  • Template literals provide a convenient way to create strings with embedded expressions. Example:
  const name = "Ramu";
  const greeting = `Hello, ${name}!`;
Enter fullscreen mode Exit fullscreen mode

Can you give an example of a curry function and why this syntax offers an advantage?

  • A curry function transforms a multi-argument function into a sequence of single-argument functions. This can enhance code flexibility and readability.

Example

const curry = (fn) => (a) => (b) => fn(a, b);
const add = (a, b) => a + b;
const curriedAdd = curry(add);
console.log(curriedAdd(1)(2)); // 3
Enter fullscreen mode Exit fullscreen mode

What are the benefits of using spread syntax and how is it different from rest syntax?

  • Spread syntax is used to expand elements of an array or properties of an object, while rest syntax is used to collect parameters into an array or properties into an object.

Example

// Spread Syntax
const numbers = [1, 2, 3];
const newNumbers = [...numbers, 4, 5]; // [1, 2, 3, 4, 5]

// Rest Syntax
const { name, ...rest } = { name: "Ramu", age: 24, city: "Bangalore" }; // rest is { age: 24, city: 'Bangalore' }
Enter fullscreen mode Exit fullscreen mode

How can you share code between files?

  • Use module systems like CommonJS or ES6 Modules to import/export code between files.
// constant.js
export const BASE_URL = "https://dev.to/bugudiramu";

// app.js
import { BASE_URL } from "./constant.js";
Enter fullscreen mode Exit fullscreen mode

Why might you want to create static class members?

  • Static class members are shared across all instances of a class, providing a way to implement utility functions or properties that belong to the class itself.

Example:

class Circle {
  static PI = 3.14;

  static calculateArea(radius) {
    return this.PI * radius * radius;
  }
}

const area = Circle.calculateArea(5);
console.log(area); // 78.5
Enter fullscreen mode Exit fullscreen mode

In this example, PI is a static property shared among all instances, and calculateArea is a static method that doesn't require creating an instance of the class.

What is the difference between while and do-while loops in JavaScript?

In JavaScript, the while loop runs a code block repeatedly as long as a specified condition is true. However, it checks the condition before the first iteration.

On the other hand, the do-while loop also repeats a code block based on a condition, but it ensures that the block is executed at least once before checking the condition.

Example

// Using while loop
let i = 0;
while (i < 5) {
  console.log(`While loop: ${i}`);
  i++;
}

// Using do-while loop
let j = 0;
do {
  console.log(`Do-while loop: ${j}`);
  j++;
} while (j < 5);
Enter fullscreen mode Exit fullscreen mode

What is a promise? Where and how would you use a promise?

  • A promise represents the eventual completion or failure of an asynchronous operation and allows you to handle the result or error in a more structured way. Promises are commonly used with asynchronous tasks like fetching data or making API calls.
function getUser() {
  const user = { name: "Ramu", age: 24 };
  return new Promise((resolve, reject) => {
    if (Object.keys(user).length > 0) {
      setTimeout(() => {
        resolve(user);
      }, 1000);
    } else {
      reject("User not found");
    }
  });
}

getUser()
  .then((user) => console.log(user))
  .catch((err) => console.log(err));
Enter fullscreen mode Exit fullscreen mode

Discuss how you might use Object-Oriented Programming principles when coding with JavaScript.

When coding in JavaScript, Object-Oriented Programming (OOP) principles can enhance your code structure.

Encapsulation:
Encapsulation involves bundling data and methods into a single unit. In JavaScript, you can achieve this using constructor functions or classes.

Inheritance:
Inheritance allows a new object to inherit properties and methods from an existing object. In JavaScript, the prototype chain facilitates inheritance.

Polymorphism:
Polymorphism enables objects to take on multiple forms. In JavaScript, achieve polymorphism through method overriding or interface implementation.

Example:

class Animal {
  constructor(name) {
    this.name = name;
  }

  makeSound() {
    console.log("Generic animal sound");
  }
}

class Dog extends Animal {
  makeSound() {
    console.log("Woof!");
  }
}

const myDog = new Dog("Buddy");
myDog.makeSound(); // Outputs: Woof!
Enter fullscreen mode Exit fullscreen mode

In this example, Dog inherits from Animal, demonstrating encapsulation, inheritance, and polymorphism in a simple JavaScript class hierarchy.


Thank you for reading this far; your support means a lot! If you have any questions, please don't hesitate to ask in the comments. Don't forget to like and share the article – your appreciation is highly valued. Your feedback and suggestions are also more than welcome. 🙏👍😊

Top comments (0)