JavaScript Interview Questions and Answers

ECMAScript fundamentals, closures, prototypes, event loop, async patterns, DOM manipulation and modern ES6+ features.

Practise 10 random 528 peer-reviewed questions
JavaScript Interview Syllabus & Preparation Strategy

Whether you are preparing for entry-level JavaScript interview questions for freshers or senior software engineer interview questions addressing concurrency, scalability, and system architecture, this track provides peer-reviewed model answers with syntax walkthroughs, edge cases, and practical interview tips.

1 What are the possible ways to create objects in JavaScript? Easy

There are many ways to create objects in javascript as mentioned below:

  1. Object literal syntax:

The object literal syntax (or object initializer), is a comma-separated set of name-value pairs wrapped in curly braces.

       var object = {
         name: "Sudheer",
         age: 34,
       };
       

Object literal property values can be of any data type, including array, function, and nested object.

Note: This is one of the easiest ways to create an object and it's most commonly used for creating simple, ad-hoc objects.

  1. Object constructor:

The simplest way to create an empty object is using the Object constructor. Currently this approach is not recommended.

       var object = new Object();
       

The Object() is a built-in constructor function so "new" keyword is not required for creating plain objects. The above code snippet can be re-written as:

       var object = Object();
       

However, Object() can be used to either create a plain object or convert a given value into its corresponding object wrapper, whereas new Object() is specifically used to explicitly create a new object instance.

  1. Object's create method:

The create method of Object is used to create a new object by passing the specified prototype object and properties as arguments, i.e., this pattern is helpful to create new objects based on existing objects. In other words, this is useful for setting up prototypal inheritance. The second argument is optional and it is used to create properties on a newly created object.

The following code creates a new empty object whose prototype is null.

       var object = Object.create(null);
       

The following example creates an object along with additional new properties.

       let vehicle = {
         wheels: "4",
         fuelType: "Gasoline",
         color: "Green",
       };
       let carProps = {
         type: {
           value: "Volkswagen",
         },
         model: {
           value: "Golf",
         },
       };

       var car = Object.create(vehicle, carProps);
       console.log(car);
       
  1. Function constructor:

In this approach, create any function and apply the new operator to create object instances. This was the main way to do constructor-based OOP before ES6 classes.

       function Person(name) {
         this.name = name;
         this.age = 21;
       }
       var object = new Person("Sudheer");
       
  1. Function constructor with prototype:

This is similar to function constructor but it uses prototype for their properties and methods. Using prototype means you're sharing methods/properties across instances, which saves memory and improve performance.

       function Person() {}
       Person.prototype.name = "Sudheer";
       var object = new Person();
       

This is equivalent to creating an instance with Object.create method with a function prototype and then calling that function with an instance and parameters as arguments.

       function func(x, y, z) {
        this.x = x;
        this.y = y;
        this.z = z;
       }

       var instance = new func(1, 2, 3);
       

(OR)

       function func(x, y, z) {
          this.x = x;
          this.y = y;
          this.z = z;
       }
       // Create a new instance using function prototype.
       var newInstance = Object.create(func.prototype);

       // Call the function
       var result = func.call(newInstance, 1, 2, 3);

       // If the result is a non-null object then use it otherwise just use the new instance.
       console.log(result && typeof result === 'object' ? result : newInstance);
       
  1. Object's assign method:

The Object.assign method is used to copy all the properties from one or more source objects and stores them into a target object. This is mainly used for cloning and merging

The following code creates a new staff object by copying properties of his working company and the car he owns.

       const orgObject = { company: "XYZ Corp" };
       const carObject = { name: "Toyota" };
       const staff = Object.assign({}, orgObject, carObject);
       
  1. ES6 Class syntax:

ES6 introduces class feature to create objects. This is syntactic sugar over the prototype-based system.

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

       var object = new Person("Sudheer");
       
  1. Singleton pattern:

A Singleton is an object which can only be instantiated one time. Repeated calls to its constructor return the same instance. This way one can ensure that they don't accidentally create multiple instances.

##### Singleton with Closure (Classic JS Pattern)

        const Singleton = (function () {
        let instance;

        function createInstance() {
          return { name: "Sudheer" };
        }

        return {
          getInstance: function () {
            if (!instance) {
              instance = createInstance();
            }
            return instance;
          }
        };
        })();

        // Usage
        const obj1 = Singleton.getInstance();
        const obj2 = Singleton.getInstance();

        console.log(obj1 === obj2); // true
        

In modern JavaScript applications, singletons are commonly implemented using ES6 modules for their built-in caching behavior, or closures for encapsulated state management.

2 What is the Difference Between call, apply, and bind? Easy

In JavaScript, call, apply, and bind are methods that allow you to control the context (this value) in which a function is executed. While their purposes are similar, they differ in how they handle arguments and when the function is invoked.

---

#### call

  • Description:

The call() method invokes a function immediately, allowing you to specify the value of this and pass arguments individually (comma-separated).

  • Syntax:
    func.call(thisArg, arg1, arg2, ...)
    
  • Example:
    var employee1 = { firstName: "John", lastName: "Rodson" };
    var employee2 = { firstName: "Jimmy", lastName: "Baily" };

    function invite(greeting1, greeting2) {
      console.log(
        greeting1 + " " + this.firstName + " " + this.lastName + ", " + greeting2
      );
    }

    invite.call(employee1, "Hello", "How are you?"); // Hello John Rodson, How are you?
    invite.call(employee2, "Hello", "How are you?"); // Hello Jimmy Baily, How are you?
    

---

#### apply

  • Description:

The apply() method is similar to call(), but it takes the function arguments as an array (or array-like object) instead of individual arguments.

  • Syntax:
    func.apply(thisArg, [argsArray])
    
  • Example:
    var employee1 = { firstName: "John", lastName: "Rodson" };
    var employee2 = { firstName: "Jimmy", lastName: "Baily" };

    function invite(greeting1, greeting2) {
      console.log(
        greeting1 + " " + this.firstName + " " + this.lastName + ", " + greeting2
      );
    }

    invite.apply(employee1, ["Hello", "How are you?"]); // Hello John Rodson, How are you?
    invite.apply(employee2, ["Hello", "How are you?"]); // Hello Jimmy Baily, How are you?
    

---

#### bind

  • Description:

The bind() method creates a new function with a specific this value and, optionally, preset initial arguments. Unlike call and apply, bind does not immediately invoke the function; instead, it returns a new function that you can call later.

  • Syntax:
    var boundFunc = func.bind(thisArg[, arg1[, arg2[, ...]]])
    
  • Example:
    var employee1 = { firstName: "John", lastName: "Rodson" };
    var employee2 = { firstName: "Jimmy", lastName: "Baily" };

    function invite(greeting1, greeting2) {
      console.log(
        greeting1 + " " + this.firstName + " " + this.lastName + ", " + greeting2
      );
    }

    var inviteEmployee1 = invite.bind(employee1);
    var inviteEmployee2 = invite.bind(employee2);

    inviteEmployee1("Hello", "How are you?"); // Hello John Rodson, How are you?
    inviteEmployee2("Hello", "How are you?"); // Hello Jimmy Baily, How are you?
    

---

#### Summary

| Method | Invokes Function Immediately? | How Arguments Are Passed | Returns |
|--------|-------------------------------|----------------------------------|--------------|
| call | Yes | Comma-separated list | Function's result |
| apply| Yes | Array or array-like object | Function's result |
| bind | No | (Optional) preset, then rest | New function |

---

## Key Points

  • call and apply are almost interchangeable; both invoke the function immediately, but differ in how arguments are passed.
  • _Tip:_ "Call is for Comma-separated, Apply is for Array."
  • bind does not execute the function immediately. Instead, it creates a new function with the specified this value and optional arguments, which can be called later.
  • Use call or apply when you want to immediately invoke a function with a specific this context. Use bind when you want to create a new function with a specific this context to be invoked later.

---

3 What is JSON and its common operations? Easy

JSON (JavaScript Object Notation) is a lightweight, text-based data format that uses JavaScript object syntax for structuring data. It was popularized by Douglas Crockford and is widely used for transmitting data between a server and a client in web applications. JSON files typically have a .json extension and use the MIME type application/json.

#### Common Operations with JSON

  1. Parsing: Transforming a JSON-formatted string into a native JavaScript object.
      const obj = JSON.parse(jsonString);
      
  • Example:
        const jsonString = '{"name":"John","age":30}';
        const obj = JSON.parse(jsonString);  // { name: "John", age: 30 }
        
  1. Stringification: Converting a JavaScript object into a JSON-formatted string, commonly used for data transmission or storage.
      const jsonString = JSON.stringify(object);
      
  • Example:
        const obj = { name: "Jane", age: 25 };
        const jsonString = JSON.stringify(obj);  // '{"name":"Jane","age":25}'
        
4 What is the purpose of the array slice method? Easy

The slice() method in JavaScript is used to extract a section of an array, returning a new array containing the selected elements. It does not modify the original array. The method takes two arguments:

  • start: The index at which extraction begins (inclusive).
  • end (optional): The index before which to end extraction (exclusive). If omitted, extraction continues to the end of the array.

You can also use negative indices, which count from the end of the array.

#### Examples:

    let arrayIntegers = [1, 2, 3, 4, 5];

    let arrayIntegers1 = arrayIntegers.slice(0, 2);    // [1, 2]
    let arrayIntegers2 = arrayIntegers.slice(2, 3);    // [3]
    let arrayIntegers3 = arrayIntegers.slice(4);       // [5]
    let arrayIntegers4 = arrayIntegers.slice(-3, -1);  // [3, 4]
    

Note:
The slice() method does not mutate (change) the original array; instead, it returns a new array containing the extracted elements.

5 What is the purpose of the array splice method? Easy

The splice() method in JavaScript is used to add, remove, or replace elements within an array. Unlike slice(), which creates a shallow copy and does not alter the original array, splice() modifies the original array in place and returns an array containing the removed elements.

#### Syntax

    array.splice(start, deleteCount, item1, item2, ...)
    
  • start: The index at which to start changing the array.
  • deleteCount: (Optional) The number of elements to remove from the array. If omitted, all elements from the start index to the end of the array will be removed.
  • item1, item2, ...: (Optional) Elements to add to the array, starting at the start position.

#### Examples

    let arrayIntegersOriginal1 = [1, 2, 3, 4, 5];
    let arrayIntegersOriginal2 = [1, 2, 3, 4, 5];
    let arrayIntegersOriginal3 = [1, 2, 3, 4, 5];

    // Remove the first two elements
    let arrayIntegers1 = arrayIntegersOriginal1.splice(0, 2); 
    // arrayIntegers1: [1, 2]
    // arrayIntegersOriginal1 (after): [3, 4, 5]

    // Remove all elements from index 3 onwards
    let arrayIntegers2 = arrayIntegersOriginal2.splice(3);     
    // arrayIntegers2: [4, 5]
    // arrayIntegersOriginal2 (after): [1, 2, 3]

    // Remove 1 element at index 3, then insert "a", "b", "c" at that position
    let arrayIntegers3 = arrayIntegersOriginal3.splice(3, 1, "a", "b", "c"); 
    // arrayIntegers3: [4]
    // arrayIntegersOriginal3 (after): [1, 2, 3, "a", "b", "c", 5]
    

Note:

  • The splice() method modifies the original array.
  • It returns an array containing the elements that were removed (if any).
  • You can use it both to remove and insert elements in a single operation.
6 What is the difference between slice and splice? Easy

Here are the key differences between slice() and splice() methods in JavaScript arrays:

| slice() | splice() |
| ------------------------------------------------- | --------------------------------------------------- |
| Does not modify the original array (immutable) | Modifies the original array (mutable) |
| Returns a shallow copy (subset) of selected elements | Returns an array of the removed elements |
| Used to extract elements from an array | Used to add, remove, or replace elements in an array |
| Syntax: array.slice(start, end) | Syntax: array.splice(start, deleteCount, ...items) |

Summary:

  • Use slice() when you want to copy or extract elements without altering the original array.
  • Use splice() when you need to add, remove, or replace elements and want to change the original array.
7 How do you compare Object and Map? Easy

Objects and Maps both allow you to associate keys with values, retrieve those values, delete keys, and check if a key exists. Historically, Objects have been used as Maps, but there are several key differences that make Map a better choice in certain scenarios:

| Feature | Object | Map |
|--------------------------|-----------------------------------------------------|----------------------------------------------------------|
| Key Types | Only strings and symbols are valid keys | Any value can be used as a key (objects, functions, primitives) |
| Key Order | Keys are unordered (in practice, insertion order is mostly preserved for string keys, but not guaranteed) | Keys are ordered by insertion; iteration follows insertion order |
| Size Property | No built-in way to get the number of keys; must use Object.keys(obj).length | Use the .size property for the number of entries |
| Iterability | Not directly iterable; must use Object.keys, Object.values, or Object.entries | Directly iterable with for...of, .keys(), .values(), .entries() |
| Prototype | Has a prototype chain; may have default properties that can collide with custom keys (can be avoided with Object.create(null)) | Does not have a prototype, so there are no default keys |
| Performance | May be less efficient for frequent additions/removals | Optimized for frequent additions and deletions |
| Serialization | Can be easily serialized to JSON | Cannot be directly serialized to JSON |

8 What is the difference between == and === operators? Easy

JavaScript provides two types of equality operators:

  • Loose equality (==, !=): Performs type conversion if the types differ, comparing values after converting them to a common type.
  • Strict equality (===, !==): Compares both value and type, without any type conversion.

#### Strict Equality (===)

  • Two strings are strictly equal if they have exactly the same sequence of characters and length.
  • Two numbers are strictly equal if they have the same numeric value.
  • Special cases:
  • NaN === NaN is false
  • +0 === -0 is true
  • Two booleans are strictly equal if both are true or both are false.
  • Two objects are strictly equal if they refer to the same object in memory.
  • null and undefined are not strictly equal.

#### Loose Equality (==)

  • Converts operands to the same type before making the comparison.
  • null == undefined is true.
  • "1" == 1 is true because the string is converted to a number.
  • 0 == false is true because false is converted to 0.

#### Examples:

    0 == false            // true      (loose equality, type coercion)
    0 === false           // false     (strict equality, different types)
    1 == "1"              // true      (string converted to number)
    1 === "1"             // false     (different types)
    null == undefined     // true      (special case)
    null === undefined    // false     (different types)
    '0' == false          // true      ('0' is converted to 0)
    '0' === false         // false     (different types)
    NaN == NaN            // false     (NaN is never equal to itself)
    NaN === NaN           // false
    [] == []              // false     (different array objects)
    [] === []             // false
    {} == {}              // false     (different object references)
    {} === {}             // false
    
9 What are lambda expressions or arrow functions? Easy

Arrow functions (also known as "lambda expressions") provide a concise syntax for writing function expressions in JavaScript. Introduced in ES6, arrow functions are often shorter and more readable, especially for simple operations or callbacks.

#### Key Features:

  • Arrow functions do not have their own this, arguments, super, or new.target bindings. They inherit these from their surrounding (lexical) context.
  • They are best suited for non-method functions, such as callbacks or simple computations.
  • Arrow functions cannot be used as constructors and do not have a prototype property.
  • They also cannot be used with new, yield, or as generator functions.

#### Syntax Examples:

    const arrowFunc1 = (a, b) => a + b;    // Multiple parameters, returns a + b
    const arrowFunc2 = a => a * 10;        // Single parameter (parentheses optional), returns a * 10
    const arrowFunc3 = () => {};           // No parameters, returns undefined
    const arrowFunc4 = (a, b) => {
      // Multiple statements require curly braces and explicit return
      const sum = a + b;
      return sum * 2;
    };
    
10 What is a first class function? Easy

In JavaScript, first-class functions(first-class citizens) mean that functions are treated like any other variable. That means:

  1. You can assign a function to a variable.
  2. You can pass a function as an argument to another function.
  3. You can return a function from another function.

This capability enables powerful patterns like callbacks, higher-order functions, event handling, and functional programming in JavaScript.

For example, the handler function below is assigned to a variable and then passed as an argument to the addEventListener method.

    const handler = () => console.log("This is a click handler function");
    document.addEventListener("click", handler);
    
11 What is a first order function? Easy

A first-order function is a function that doesn’t accept another function as an argument and doesn’t return a function as its return value. i.e, It's a regular function that works with primitive or non-function values.

    const firstOrder = () => console.log("I am a first order function!");
    
12 What is a higher order function? Easy

A higher-order function is a function that either accepts another function as an argument, returns a function as its result, or both. This concept is a core part of JavaScript's functional programming capabilities and is widely used for creating modular, reusable, and expressive code.

The syntactic structure of higher order function will be explained with an example as follows,

      // First-order function (does not accept or return another function)
      const firstOrderFunc = () => 
        console.log("Hello, I am a first-order function");

      // Higher-order function (accepts a function as an argument)
      const higherOrder = (callback) => callback();

      // Passing the first-order function to the higher-order function
      higherOrder(firstOrderFunc);
      

In this example:

  1. firstOrderFunc is a regular (first-order) function.
  1. higherOrder is a higher-order function because it takes another function as an argument.
  1. firstOrderFunc is also called a callback function because it is passed to and executed by another function.
13 What is a unary function? Easy

A unary function (also known as a monadic function) is a function that accepts exactly one argument. The term "unary" simply refers to the function's arity—the number of arguments it takes.

Let us take an example of unary function,

    const unaryFunction = (a) => console.log(a + 10); // This will add 10 to the input and log the result
    unaryFunction(5); // Output: 15
    

In this example:

  • unaryFunction takes a single parameter a, making it a unary function.
  • It performs a simple operation: adding 10 to the input and printing the result.
14 What is a pure function? Easy

A pure function is a function whose output depends only on its input arguments and produces no side effects. This means that given the same inputs, a pure function will always return the same output, and it does not modify any external state or data.

Let's take an example to see the difference between pure and impure functions,

#### Example: Pure vs. Impure Functions

    // Impure Function
    let numberArray = [];
    const impureAddNumber = (number) => numberArray.push(number);

    // Pure Function
    const pureAddNumber = (number) => (inputArray) =>
      inputArray.concat([number]);

    // Usage
    console.log(impureAddNumber(6)); // returns 1
    console.log(numberArray);        // returns [6]

    console.log(pureAddNumber(7)(numberArray)); // returns [6, 7]
    console.log(numberArray);                   // remains [6]
    
  • impureAddNumber changes the external variable numberArray and returns the new length of the array, making it impure.
  • pureAddNumber creates a new array with the added number and does not modify the original array, making it pure.
15 What are the benefits of pure functions? Easy

Some of the major benefits of pure functions are listed below,

  • Easier testing: Since output depends only on input, pure functions are simple to test.
  • Predictability: No hidden side effects make behavior easier to reason about.
  • Immutability: Pure functions align with ES6 best practices, such as preferring const over let, supporting safer and more maintainable code.
  • No side effects: Reduces bugs related to shared state or mutation.
16 What is the purpose of the let keyword? Easy

The let keyword in JavaScript is used to declare a block-scoped local variable. This means that variables declared with let are only accessible within the block, statement, or expression where they are defined. This is a significant improvement over the older var keyword, which is function-scoped (or globally-scoped if declared outside a function), and does not respect block-level scoping.

#### Key Features of let:

  • Block Scope: The variable exists only within the nearest enclosing block (e.g., inside an {} pair).
  • No Hoisting Issues: While let declarations are hoisted, they are not initialized until the code defining them is executed. Accessing them before declaration results in a ReferenceError (temporal dead zone).
  • No Redeclaration: The same variable cannot be declared twice in the same scope with let.

#### Example:

    let counter = 30;
    if (counter === 30) {
      let counter = 31;
      console.log(counter); // Output: 31 (block-scoped variable inside if-block)
    }
    console.log(counter); // Output: 30 (outer variable, unaffected by inner block)
    

In this example, the counter inside the if block is a separate variable from the one outside. The let keyword ensures that both have their own distinct scope.

In summary, you need to use let when you want variables to be limited to the block in which they are defined, preventing accidental overwrites and bugs related to variable scope.

17 What is the difference between let and var? Easy

You can list out the differences in a tabular format

| var | let |
| -------------------------------------------------------------- | --------------------------------------------- |
| It has been available from the beginning of JavaScript | Introduced as part of ES6 |
| It has function scope | It has block scope |
| Variable declaration will be hoisted, initialized as undefined | Hoisted but not initialized |
| It is possible to re-declare the variable in the same scope | It is not possible to re-declare the variable |

Let's take an example to see the difference,

    function userDetails(username) {
      if (username) {
        console.log(salary); // undefined due to hoisting
        console.log(age); // ReferenceError: Cannot access 'age' before initialization
        let age = 30;
        var salary = 10000;
      }
      console.log(salary); //10000 (accessible due to function scope)
      console.log(age); //error: age is not defined(due to block scope)
    }
    userDetails("John");
    
18 What is the reason to choose the name let as a keyword? Easy

The keyword let was chosen because it originates from mathematical notation, where "let" is used to introduce new variables (for example, "let x = 5"). This term was adopted by several early programming languages such as Scheme and BASIC, establishing a tradition in computer science. JavaScript follows this convention by using let to declare variables with block scope, providing a modern alternative to var. The choice helps make the language more familiar to programmers coming from other languages and aligns with the mathematical practice of variable assignment.

19 How do you redeclare variables in a switch block without an error? Easy

When you try to redeclare variables using let or const in multiple case clauses of a switch statement, you will get a SyntaxError. This happens because, in JavaScript, all case clauses within a switch statement share the same block scope. For example:

    let counter = 1;
    switch (x) {
      case 0:
        let name;
        break;
      case 1:
        let name; // SyntaxError: Identifier 'name' has already been declared
        break;
    }
    

To avoid this error, you can create a new block scope within each case clause by wrapping the code in curly braces {}. This way, each let or const declaration is scoped only to that block, and redeclaration errors are avoided:

    let counter = 1;
    switch (x) {
      case 0: {
        let name;
        // code for case 0
        break;
      }
      case 1: {
        let name; // No SyntaxError
        // code for case 1
        break;
      }
    }
    

That means, to safely redeclare variables in different cases of a switch statement, wrap each case’s code in its own block using curly braces. This ensures each variable declaration is scoped to its specific case block.

20 What is an IIFE (Immediately Invoked Function Expression)? Easy

IIFE (Immediately Invoked Function Expression) is a JavaScript function that runs as soon as it is defined. The signature of it would be as below,

    (function () {
      // logic here
    })();
    

The primary reason to use an IIFE is to obtain data privacy because any variables declared within the IIFE cannot be accessed by the outside world. i.e, If you try to access variables from the IIFE then it throws an error as below,

    (function () {
      var message = "IIFE";
      console.log(message);
    })();
    console.log(message); //Error: message is not defined
    
Showing 20 of 528 questions

Frequently Asked Questions About JavaScript Interviews

What do hiring managers evaluate in JavaScript technical rounds?

Technical interviewers look for foundational fluency, idiomatic syntax, clarity when communicating complex logic, and awareness of performance trade-offs (e.g. memory footprint, render performance, and network latency) in production environments.

What are the best interview tips for practicing JavaScript questions?

Use active recall: summarize each answer in your own words before revealing the model solution. Focus on explaining why a certain approach is chosen rather than just memorizing code syntax.