FrontendDeveloper.in

JavaScript Interview Questions

  • Question 1

    What are the possible ways to create objects in JavaScript

    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.

  • Question 2

    What is a prototype chain

    The prototype chain is a core concept in JavaScript’s inheritance model. It allows objects to inherit properties and methods from other objects. When you try to access a property or method on an object, JavaScript first looks for it on that object itself. If it’s not found, the engine looks up the object's internal [[Prototype]] reference (accessible via Object.getPrototypeOf(obj) or the deprecated __proto__ property) and continues searching up the chain until it finds the property or reaches the end (usually null).

    For objects created via constructor functions, the prototype chain starts with the instance, then refers to the constructor’s .prototype object, and continues from there. For example:

    function Person() {}
    const person1 = new Person();
    
    console.log(Object.getPrototypeOf(person1) === Person.prototype); // true
    

    This mechanism allows for property and method sharing among objects, enabling code reuse and a form of inheritance.

    Summary:

    • The prototype chain enables inheritance in JavaScript.
    • If a property isn’t found on an object, JavaScript looks up its prototype chain.
    • The prototype of an object instance can be accessed with Object.getPrototypeOf(obj) or __proto__.
    • The prototype of a constructor function is available via Constructor.prototype.
    • The chain ends when the prototype is null.

    The prototype chain among objects appears as below,

    Screenshot

  • Question 3

    What is the Difference Between `call`, `apply`, and `bind`

    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

    MethodInvokes Function Immediately?How Arguments Are PassedReturns
    callYesComma-separated listFunction's result
    applyYesArray or array-like objectFunction's result
    bindNo(Optional) preset, then restNew 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.


  • Question 4

    What is JSON and its common operations

    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}'
    
  • Question 5

    What is the purpose of the array slice method

    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.

  • Question 6

    What is the purpose of the array splice method

    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.
  • Question 7

    What is the difference between slice and splice

    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 elementsReturns an array of the removed elements
    Used to extract elements from an arrayUsed 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.
  • Question 8

    How do you compare Object and Map

    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:

    FeatureObjectMap
    Key TypesOnly strings and symbols are valid keysAny value can be used as a key (objects, functions, primitives)
    Key OrderKeys 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 PropertyNo built-in way to get the number of keys; must use Object.keys(obj).lengthUse the .size property for the number of entries
    IterabilityNot directly iterable; must use Object.keys, Object.values, or Object.entriesDirectly iterable with for...of, .keys(), .values(), .entries()
    PrototypeHas 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
    PerformanceMay be less efficient for frequent additions/removalsOptimized for frequent additions and deletions
    SerializationCan be easily serialized to JSONCannot be directly serialized to JSON
  • Question 9

    What is the difference between == and === operators

    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
    
  • Question 10

    What are lambda expressions or arrow functions

    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;
    };
    
  • Question 11

    What is a first class function

    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);
    
  • Question 12

    What is a first order function

    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!");
    
  • Question 13

    What is a higher order function

    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.

    2. higherOrder is a higher-order function because it takes another function as an argument.

    3. firstOrderFunc is also called a callback function because it is passed to and executed by another function.

  • Question 14

    What is a unary function

    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.
  • Question 15

    What is the currying function

    Currying is the process of transforming a function with multiple arguments into a sequence of nested functions, each accepting only one argument at a time.

    This concept is named after mathematician Haskell Curry, and is commonly used in functional programming to enhance modularity and reuse.

    Before Currying (Normal n-ary Function)

    const multiArgFunction = (a, b, c) => a + b + c;
    
    console.log(multiArgFunction(1, 2, 3)); // Output: 6
    

    This is a standard function that takes three arguments at once.

    After Currying (Unary Function Chain)

    const curryUnaryFunction = (a) => (b) => (c) => a + b + c;
    
    console.log(curryUnaryFunction(1));       // Returns: function (b) => ...
    console.log(curryUnaryFunction(1)(2));    // Returns: function (c) => ...
    console.log(curryUnaryFunction(1)(2)(3)); // Output: 6
    
    

    Each function in the chain accepts one argument and returns the next function, until all arguments are provided and the final result is computed.

    Benefits of Currying

    • Improves code reusability → You can partially apply functions with known arguments.

    • Enhances functional composition → Easier to compose small, pure functions.

    • Encourages clean, modular code → You can split logic into smaller single-responsibility functions.

Get LinkedIn Premium at Rs 399