Skip to main content

Command Palette

Search for a command to run...

The Magic of this, call(), apply() and bind() in JavaScript

Updated
5 min read
The Magic of this, call(), apply() and bind() in JavaScript

What this means in JavaScript (simple explanation)

Many people finds the concept of this very confusing but we will uncover this in very simple terms so that you can never forget.

In simple terms, this means who is calling the function, it represents the current execution context. It also depends where you are using this , if you are using it in browser then it represents windows object & in case of node environment it represents empty object.

When a function runs, this refers to the object that is executing (calling) that function.

console.log(this);    // in browser -> {}
console.log(this);    // in node -> window object 

this inside normal functions

this behavior is different in normal functions vs arrow functions. We will understand this behavior later in objects by various examples let's see.

In case of browser when we use this in different types of functions output is always a window object, but in case of node environment it represent global object.

function show1() {
    console.log(this);
}
show1();      // Window (or global object)

const show2 = function() {
    console.log(this);
};
show2();     // Window (or global object)

const show3 = () => {
    console.log(this);
};
show3();     // Window (or global object)

this inside objects

let person = {
    name: "Rahul",
    greet() {
        console.log(this.name);
    }
};
person.greet();    // Rahul

let person = {
    name: "Rahul",
    greet: () => {
        console.log(this.name);
    }
};
person.greet();    // undefined

Here this refers to the person object such that person.name will print "Rahul". As in this case person is calling the greet function that's why this inside greet function refers to person.

In case of normal functions, this always refers to the upper scope in which they are written means here this comes under greet & greet comes under person so now this will points to the person object. Its a simple trick to remember.

But in case of arrow functions, this always refers to the upper of the upper scope in which they are written means here this comes under greet and greet comes under person and then person comes under window object or global object but window.name doesn't exist that's why undefined prints.

const filmSet = {
  crew: "Spot boys",

  prepareProps() {
    console.log(`Outer this.crew: ${this.crew}`);

    function arrangeChairs() {
      console.log(`Inner this.crew: ${this.crew}`);
    }
    arrangeChairs();

    const arrangeLights = () => {
      console.log(`Arrow this.crew: ${this.crew}`);
    };
    arrangeLights();
  },
};

filmSet.prepareProps();

// Output --
// Outer this.crew: Spot boys
// Inner this.crew: undefined
// Arrow this.crew: Spot boys

What call() does

call() method borrows a this reference and give it to the function with some arguments but this reference always passed first followed by other arguments.

In other words, call() simply call the function but injecting a this reference to this function where this reference can be any object or something else.

let person1 = {
    name: "Rahul"
};
let person2 = {
    name: "Amit"
};
function greet() {
    console.log("Hello " + this.name);
}
greet.call(person1);   // Hello Rahul
greet.call(person2);   // Hello Amit

function greetUser(age) {
    console.log(`\({this} is \){age} years old`);
}
greetUser.call("kuldeep", 25);   // kuldeep is 25 years old
  • greet function is called using call() method, which takes person1 to this function

  • Now person1 object reference is embedded to this greet function

  • So in the greet function, this refers to the person1 object such that "Rahul" prints

What apply() does

apply() method is same as call() method. The only difference is in there arguments passed, in the apply() method we passed other arguments except this reference in form of an array which then automatically extracts in order.

So in call() method, arguments are passed by separated values but in case of apply() method arguments are passed in form of array.

let person = { name: "Kuldeep" };

function greet(age, city) {
    console.log(`\({this.name} is \){age} from ${city}`);
}

greet.apply(person, [25, "Delhi"]);   // Kuldeep is 25 from Delhi

What bind() does

bind() method is same as call() method. The only difference is that it does not runs immediately means it returns the function reference in some variable and whenever we want to call the function, we can just call the variable using parenthesis.

In other words, bind() simply binds the output and hold it to a variable, and whenever we want to use it, we can just simply call it.

let person = { name: "Kuldeep" };

function greet(age, city) {
    console.log(`\({this.name} is \){age} from ${city}`);
}

let greetUser = greet.bind(person, 25);
greetUser("Delhi");         // Kuldeep is 25 from Delhi 

Difference between call, apply, and bind

Feature call() apply() bind()
Calls function immediately? Yes Yes No
Arguments format Normal Array Normal
Returns new function? No No Yes

Overall core functionality is same for all these 3 methods, differ in their uses cases simply.