“this” in JavaScript DEMYSTIFIED!!

Ever since I started learning and coding in JavaScript, the one thing that has always puzzled me and messed with my head was the this keyword. It gave me nightmares when I started learning React. It took me quite a while to understand and actually grasp the concepts of this and in this article, I have tried to impart my learnings and notes to all the fellow JavaScript devs out there. Sit tight and thank me later 🌝

P.S : the keyword this has been used in bold and italic format (everywhere apart from code) to avoid confusion (this).

Before starting to learn about what this keyword is, firstly let us understand why JavaScript has a this keyword in first place.

this keyword allows us to reuse functions with different contexts, or in other words, it allows us to decide which object should be focal while invoking a function or a method.

Imagine we have one function and we have a bunch of objects with similar properties, we want that function to work throughout all of our objects. So in this blog, we are going to break down the this keyword in four rules:

  • Implicit Binding
  • Explicit Binding
  • new Binding
  • window Binding

The first thing you need to ask yourself whenever you are trying to figure out what the this keyword is, is this question :

Where is the damn function invoked?

Whenever you are trying to figure out what the this keyword is, you have to look at the when the function was invoked.

var sayName = function(name) {
  console.log("Hello " + name);
}

If I were to ask you what this function is doing, or more specifically, what is the name the function is going to console.log, you can’t say it until the function is invoked.

sayName('Rajat')

This is the exact same idea with this keyword, you can’t know the meaning of it unless it is invoked.

Now let’s look at all the rules one by one:

  1. Implicit Binding : It is the most common rule and it is found in almost about 80% of the usecases when you are trying to figure out what the this keyword is
var me = {
  name: 'Rajat',
  age: 23,
  sayName: function() {
    console.log(this.name);
  }
};
me.sayName();

Now the question is trying to figure out what does the underlined this keyword in the above code reference?

Well, implicit binding says that when a function is invoked, look to the left of the dot(.), that is what this keyword is gonna reference. So, here the log value will be ‘Rajat’.

var sayNameMixin = function(obj) {
  obj.sayName=  function() {
    console.log(this.name);
  }
} ;
var me = {
  name: 'Rajat',
  age: 23
};
var you = {
  name: 'Subham',
  age: 22
};
sayNameMixin(me);
sayNameMixin(you);
me.sayName();                //-> Rajat
you.sayName();              //-> Subham

Because, the one in the left of dot is what the this keyword references. Let’s see another example.

var Person = function(name, age) {
  return {
    name: name,
    age: age,
    sayName: function() {
      console.log(this.name);
    }
  }
};
var aman = Person('Aman', 23);
aman.sayName();            //->Aman

But what if we made this a bit more complex.

var Person = function(name, age) {
  return {
    name: name,
    age: age,
    sayName: function() {
      console.log(this.name);
    },
    mother: {
      name: 'Mom'
      sayName: function() {
      console.log(this.name);
     }
   }
  };
};
var aman = Person('Aman', 23);
aman.sayName();                      //->Aman
aman.mother.sayName()       //->Mom

What is on the left of dot => mother.

Does mother have a name property => Yes

So, this here will reference the name property of mother.

So, to sum it up, whenever you need to figure out what the this keyword is, look at the left of the dot where the function is invoked. If there is something, that is where the this keyword references to.

  1. Explicit Binding : Many a times, we see this functions being invoked : .apply, .bind, .call. We’ll discuss all this here in this section.

Till now we were declaring a function inside an object and we could call the function on that object and know what the this keyword referenced to. But what if the function sayName () instead of being a method on the object is a function in the global scale. For example,

sayName: function() {
  console.log(this.name);
}
var me = {
  name: 'Rajat',
  age: 23,
};

Now, we want to call this function in the context of the object (me).

sayName.call(me);                  // -> Rajat

Now, what will happen is that sayName function will be invoked and the this keyword inside of sayName is going to reference me. Here in this example, we are explicitly stating what the this keyword is.

If we wanted our function to take more parameters, we can do that simply too.

sayName: function(lan1, lan2, lan3) {
  console.log(this.name + " knows " + lan1 + ", " + lan2 + ", " + lan3);
}
var me = {
  name: 'Rajat',
  age: 23,
};
var languages = ['JavaScript', 'Typescript', 'Python'];
sayName.call(me, languages[0], languages[1], languages[2]);     
//-> Rajat knows JavaScript, Typescript, Python

Now, instead of passing arguments one by one, we could use apply function and code.

sayName.apply(me, languages);  
//-> Rajat knows JavaScript, Typescript, Python

.bind() is almost the exact same thing as .call except for one thing. It creates a brand new function after explicitly binding the this with an object.

sayName: function(lan1, lan2, lan3) {
  console.log(this.name + " knows " + lan1 + ", " + lan2 + ", " + lan3);
}
var me = {
  name: 'Rajat',
  age: 23,
};
var languages = ['JavaScript', 'Typescript', 'Python'];
var newFn = sayName.bind(me, languages[0], languages[1], languages[2]);
newFn();

So, to recap : call, apply and bind allows us to explicitly state what the this keyword is going to be in any given function. call and apply behaves the exact same way, they immediately invoke the function, with call you pass the arguments one by one and with apply, you pass them as an array. bind is the exact same thing as call, only difference being that instead of immediately invoking the function, it creates a new function which can be later invoked accordingly.


3. new Binding : This rule states that when a function is invoked with the new keyword, the this keyword inside that function is bound to the new object being constructed.

var Animal = function(color, name, type) {
  // this = {}
  this.color = color;
  this.name = name;
  this.type = type;
}
var zebra = new Animal('black and white', 'Zorro', 'Zebra');

So, what happens that JavaScript here creates a brand new object for us and save it as this (see the commented part). So, this in here is just an object.


4. window Binding :

var sayAge = function() {
  console.log(this.age);
};
var me = {
  age: 23
};
sayAge();

Here we are not specifying anything..Now what will happen??

You will notice that you get undefined. What happens is when you are calling a function that uses a this keyword and doesn’t have anything on the left of dot or does not new binding or does not use call, apply or bind, then this keyword is going to be default to the window object

So, if we do this:

window.age = 23;
sayAge();      //->23

One more scenario to keep in mind is suppose we use strict in the function above then, it will not give undefined as output but will throw a TypeError.

var sayAge = function() {
  'use strict';
  console.log(this.age);
};
var me = {
  age: 23
};
sayAge();  // Uncaught TypeError: Cannot read property 'age' of undefined

Hope this descriptive blog helped you and clear your concepts and eliminate any doubts about the damn this object in Javascript :)

Do leave your feedback and suggestion as comments.

Learn . Grow . Excel

Comments (1)

Bipin singh's photo

Best article