Skip to main content

Command Palette

Search for a command to run...

"this" keyword in JavaScript

Updated
โ€ข4 min read
"this" keyword in JavaScript

this used to be one of the most confusing topics for me. The purpose of this blog is to share little bit of what i have understood about it in past few months.

Prerequisites

I assume you have some familiarity with functions, arrow functions, scope, classes, objects and their methods in JavaScript.

What is this?

In JavaScript, we can write functions in broadly two different ways, as normal functions and as arrow functions. Value of this will differ in both types of functions, let's see how.

this in normal functions

this is just a variable/binding accessible from within a function's body, whose value is the object on which that function is called.

Let's look at some examples to verify our definition of this.

const obj = {
    name: "perry",
    fullName: "platypus " + this.name,
};

console.log(obj.fullName);

This code only logs "platypus" to console and not our object's name property. Why? Because " this is a binding accessible from within a function's body" and we were trying to access it outside any function. Let's try again while keeping that in mind.

const obj = {
    name: "perry",
    logFullName() {
        console.log("platypus " + this.name);
    },
};

obj.logFullName();

This time it will log "platypus perry" to console which shows us two things.

  1. this is indeed accessible from within a function's body.
  2. value of this was obj(that's why this's name property had the value "perry") which is the object we called logFullName method on.

Since value of this is the object we call a function upon, same function called as a method on different objects should have different values for this. Let's look at that through an example.

function speak() {
    console.log(this.name + ' says "hello"');
}

const spike = { name: "spike", speak };
const bob = { name: "bob", speak };

spike.speak(); //spike says "hello"
bob.speak(); //bob says "hello"

By looking at the output it's clear that even if it's the same function, value of this does change depending upon where we are calling it.

this in a function not called as an object's method

Now, what about the functions not called as an object's method? Such functions get called on the global object(which is called 'window' in browser and 'global' in node).

function logThis() {
    console.log(this);
}

logThis();

Running this code will print global object on browser and window object on node. Please note that this won't work while using strict mode.

this in an arrow function

So the thing with arrow functions is that they don't come with their own this binding/variable like normal functions do. Thus there's nothing to stop them from seeing the this of the surrounding scope and that's why that surrounding scope's this is the value we get when we try to reference this from within an arrow function.

const myObj = {
    data: "xyz",
    logData: () => console.log(this.data),
};

myObj.logData(); //it wil print undefined

Since arrow functions can't see the object they were called on through their this binding, it makes them not an ideal candidate for writing object methods. ๐Ÿ˜…

const myObj = {
    data: "xyz",
    logData: function () {
        setTimeout(() => console.log(this.data), 1000);
    },
};

myObj.logData(); //it wil wait for a second and then log "xyz" to console

BUT they are super useful in situations where we want to reference this from inside a local function (normal functions will simply overwrite it with their own this). The above code wouldn't work if we replace its arrow function with a normal one, since the arrow function passed to setTimeout doesn't have its own this, it can see and access its surrounding scope logData's this.

Also in normal functions, the value of this was changing depending upon the object we were calling it on. But it doesn't change like that when we use an arrow function, it's fixed depending upon where it was defined (rather than called like in case of normal functions).

function normalFunction() {
    console.log(this);
}

const arrowFunction = () => console.log(this);

const ourObj = { normalFunction, arrowFunction };

normalFunction(); //it will print window/global object
ourObj.normalFunction(); //it will print ourObj

arrowFunction(); //it will print window/global object
ourObj.arrowFunction(); //it will also print window/global object

Here we just create a normal function and an arrow function, both of which just print this. Upon running this code we can clearly see how this in normal function is changing depending upon where it is called but this in arrow function stays the same, its value depends on where it was defined.

Thanks for reading.

P
console.log(this.article + ' is really great.');
1