Call, Apply and Bind Method in Javascript

  • Let me explain these three powerful methods in detail with real-world analogies and examples.

The Core Problem They Solve

  • Before understanding these methods, let's understand why they exist.
  • In JavaScript, functions are objects, and they have a special relationship with the this keyword. The value of this depends on how a function is called, not where it's defined. Sometimes, we need to control what this refers to. That's where call, apply, and bind come in.
  • Real-world analogy: Imagine you have a universal remote control (a function). Sometimes you want it to control your TV, sometimes your AC, sometimes your music system. call, apply, and bind are like switches that let you decide which device (object) the remote will control.


1. The call() Method

What it does:

  • call() lets you invoke a function and explicitly set what this should be inside that function. You can also pass arguments one by one.

Syntax:


    functionName.call(thisArg, arg1, arg2, arg3, ...)

Basic Example:


    const person1 = {
        name: "Rahul",
        age: 25
    };

    const person2 = {
        name: "Priya",
        age: 22
    };

    function introduce(city, country) {
        console.log(`Hi, I'm ${this.name}, ${this.age} years old from ${city}, ${country}`);
    }

    // Using call to set 'this' to person1
    introduce.call(person1, "Mumbai", "India");
    // Output: Hi, I'm Rahul, 25 years old from Mumbai, India

    // Using call to set 'this' to person2
    introduce.call(person2, "Delhi", "India");
    // Output: Hi, I'm Priya, 22 years old from Delhi, India

  • What happened? We borrowed the introduce function and told it: "When you run, treat person1 (or person2) as your this."

Real-world Use Case - Function Borrowing:


    const car = {
        brand: "Toyota",
        model: "Camry",
        getDetails: function () {
            return `${this.brand} ${this.model}`;
        }
    };

    const bike = {
        brand: "Honda",
        model: "CBR"
    };

    // Borrowing car's method for bike
    console.log(car.getDetails.call(bike));
    // Output: Honda CBR

  • Why is this useful? You don't need to write the same function for bike. You just borrow it from car!


2. The apply() Method

What it does:

  • apply() works exactly like call(), but with one difference: it takes arguments as an array instead of individually.

Syntax:


    functionName.apply(thisArg, [arg1, arg2, arg3, ...])

Basic Example:


    const person = {
        name: "Amit"
    };

    function greet(greeting, punctuation) {
        console.log(`${greeting}, I'm ${this.name}${punctuation}`);
    }

    // Using apply - arguments in an array
    greet.apply(person, ["Hello", "!"]);
    // Output: Hello, I'm Amit!

When to Use apply Over call:

  • When you have arguments in an array:


    const numbers = [5, 10, 15, 20, 25];

    // Finding max value using Math.max
    const max = Math.max.apply(null, numbers);
    console.log(max); // Output: 25

    // Math.max normally needs: Math.max(5, 10, 15, 20, 25)
    // But we have an array, so apply is perfect!

  • Note: With modern JavaScript (ES6+), you can use the spread operator instead:


    const max = Math.max(...numbers); // Same result

Real-world Use Case - Function with Unknown Number of Arguments:


    function sumAll() {
        let total = 0;
        for (let i = 0; i < arguments.length; i++) {
            total += arguments[i];
        }
        return total;
    }

    const nums = [1, 2, 3, 4, 5];

    // Using apply to pass array as individual arguments
    const result = sumAll.apply(null, nums);
    console.log(result); // Output: 15


3. The bind() Method

What it does:

  • bind() is different from call and apply. Instead of calling the function immediately, it returns a new function with this permanently set to whatever you specify.

Syntax:


    const newFunction = functionName.bind(thisArg, arg1, arg2, ...)

Basic Example:


    const person = {
        name: "Neha",
        age: 28
    };

    function introduce(city) {
        console.log(`I'm ${this.name}, ${this.age} years old, living in ${city}`);
    }

    // bind creates a new function with 'this' set to person
    const introduceNeha = introduce.bind(person);

    // Call it whenever you want
    introduceNeha("Bangalore");
    // Output: I'm Neha, 28 years old, living in Bangalore

    introduceNeha("Pune");
    // Output: I'm Neha, 28 years old, living in Pune

  • Key Difference: call and apply execute the function immediately. bind gives you a new function to use later.

Real-world Use Case 1 - Event Handlers:


    const button = {
        content: "Click me!",
        click: function () {
            console.log(`${this.content} was clicked`);
        }
    };

    // Without bind - 'this' will be the button element, not our object
    // document.querySelector('button').addEventListener('click', button.click);

    // With bind - 'this' will be our button object
    document.querySelector('button').addEventListener('click', button.click.bind(button));

Real-world Use Case 2 - Partial Application:


    function multiply(a, b) {
        return a * b;
    }

    // Create a function that always multiplies by 2
    const double = multiply.bind(null, 2);

    console.log(double(5));  // Output: 10
    console.log(double(10)); // Output: 20

    // Create a function that always multiplies by 3
    const triple = multiply.bind(null, 3);

    console.log(triple(5));  // Output: 15
    console.log(triple(10)); // Output: 30

  • This is called "partial application" - you pre-fill some arguments and create a specialized function.


Quick Comparison Table

Method

Executes Immediately?

Arguments Format

Returns

call

Yes

Individual (arg1, arg2, ...)

Function result

apply

Yes

Array [arg1, arg2, ...]

Function result

bind

No

Individual (arg1, arg2, ...)

New function


Advanced Example - All Three Together:


    const calculator = {
        value: 0,
        add: function (a, b) {
            this.value = a + b;
            return this.value;
        }
    };

    const scientificCalc = {
        value: 100
    };

    // Using call
    console.log(calculator.add.call(scientificCalc, 50, 30));
    // Output: 80 (scientificCalc.value is now 80)

    // Using apply
    console.log(calculator.add.apply(scientificCalc, [20, 10]));
    // Output: 30 (scientificCalc.value is now 30)

    // Using bind
    const boundAdd = calculator.add.bind(scientificCalc);
    console.log(boundAdd(15, 25));
    // Output: 40 (scientificCalc.value is now 40)


Common Interview Question Pattern:


    const person = {
        firstName: "Virat",
        lastName: "Kohli",
        getFullName: function () {
            return this.firstName + " " + this.lastName;
        }
    };

    const anotherPerson = {
        firstName: "MS",
        lastName: "Dhoni"
    };

    // Borrowing method
    console.log(person.getFullName.call(anotherPerson));
    // Output: MS Dhoni


When to Use Each:

  • Use call when you know all arguments upfront and want to pass them individually
  • Use apply when you have arguments in an array or don't know the number of arguments
  • Use bind when you want to create a reusable function with a fixed this value (especially for event handlers or callbacks)

Key Takeaways:

  1. All three methods control what this refers to inside a function
  2. call and apply execute immediately; bind returns a new function
  3. call takes individual arguments; apply takes an array
  4. bind is perfect for creating functions to use later (callbacks, event handlers)
  5. These methods enable function borrowing - reusing methods across objects

No comments:

Post a Comment

What We're Learning Now — NumPy & Data Science Foundation

The Big Picture You've completed: ✅ Core Python ✅ FastAPI You are now starting: 🎯 Phase 1 — Python for Data Science This phas...