“call” function in JavaScript


call function calls a function with a given context (this) and arguments separately. It is defined on the prototype of Function class. It is similar to apply function in JavaScript except how it takes the arguments.

Function.prototype.call

If the context is passed as null or undefined to call then the function will be executed in the global context (window in the browser and global in node.js).

Syntax

call(thisArg, arg1, …, argN)
  • thisArg – Optional – Value to be used as this (context) while calling the function.
  • arg1, …, argN – Optional – Arguments to be passed in the function separately.

Examples

    function greet(to, from) {
        console.log(`Hello ${to}, I am ${from}`);
    }

    greet();
    greet.call(null, 'Tony', 'Steve');
Hello undefined, I am undefined
Hello Tony, I am Steve
    const time = {
        hour: 8,
        minute: 34,
        seconds: 12
    };

    function printTime() {
        console.log(`Time is ${this.hour} hours, ${this.minute} minutes and ${this.seconds} seconds.`);
    }

    printTime();
    printTime.call(time);
Time is undefined hours, undefined minutes and undefined seconds.
Time is 8 hours, 34 minutes and 12 seconds.

Can we write our own “call” function?

Let’s see if can write something close to the original call function.

    Function.prototype.myCall = function (thisArg, ...args) {
        if (thisArg === null || thisArg === undefined) {
            thisArg = globalThis;
        }

        const newFunction = this.bind(thisArg);
        return newFunction(...args);
    }
    const petCount = { cats: 2, dogs: 3, parrots: 2 };

    function printMyPetCount(owner) {
        console.log(`${owner} has ${this.cats} cats, ${this.dogs} dogs and ${this.parrots} parrots.`);
    }

    printMyPetCount();
    printMyPetCount.myCall(petCount, 'Mark');
undefined has undefined cats, undefined dogs and undefined parrots.
Mark has 2 cats, 3 dogs and 2 parrots.

Explanation

  1. Define a new function on prototype of Function class. We are doing this because we want our function to be available on functions rather taking them as argument.
  2. Check thisArg. Assign globalThis to thisArg if found null or undefined.
  3. Get a new function bounded with new context (thisArg).
  4. Execute the new function with given arguments and return the result.

References

  1. Mozilla Developer Network (MDN)