This keyword in JavaScript

If you want to understand the meaning and importance of this keyword in JavaScript just from the start, you need to ask the right questions and avoid using the wrong ones. If you want to ask something like “so what exactly this keyword means”, I will interfere abruptly and point out that this a wrong question to ask. If, on the other hand, you ask “so what exactly does this keyword mean in this particular context or environment, or scope”, I would say that you’re on a right track. And once you add “Is this keyword dynamic or static?” I would fear that I have nothing left to surprise you. And once you understand and get hang of this conventional trick in programming, you can extract all the perks it provides. Now it’s time to make a transition from philosophical, conceptual statements to more logical and practical examples.

In order to gradually understand and implement, we should take a look at how thisworks in different environments. Let’s start here with the global scope, also known as the window object. To prove that when this is used in global scope it refers to the window object, we can always ask in the console log of our browser, which has built-in JavaScript.

this === window // true
this === globalThis // true

This code proves, that when it’s called in a global environment, it points to the global object or window. With an understanding that has different meanings depending on where it’s called, let’s move forward and now try to invoke it in the function body, or function scope. Let’s try simple and gradually add functionality.

function testThis(){
console.log(this === window) // true
}
testThis()

We see in the example above, that even if inside of the function, if not explicitly told to point out to some other object, thisstill refers to window. But this statement is half true while when we try to invoke this in strict mode, it will returnfalse, while it’s more strict, apparently, and in strict mode the value of thisinside of a function is undefined.

'use strict'
function testThis(){
console.log(this === window) // false
}
testThis()

With this in mind, we can move further and create a simple function where we can understand better the usage. We can now create a constructor function (with uppercase latter) and create its instances using newkeyword.

class Country {
constructor(name, capital, passenger) {
this.name = name.charAt(0).toUpperCase() + name.slice(1);
this.capital = capital.charAt(0).toUpperCase() + capital.slice(1);
this.passenger = passenger.charAt(0).toUpperCase() + passenger.slice(1);
this.sayHello = function() {
return `Hello, ${this.passenger}, welcome to the capital of ${this.name} ${this.capital}`;
}
}
}
let france = new Country("france", "paris", 'john')
console.log(france.capital) // Paris
console.log(france.sayHello())
// Hello, John, welcome to the capital of France Paris

This a class function written in ES6, which is new syntactic sugar for a function. As we see in this example, thisdoesn’t represent the global object, but whatever is passed as a function argument when an instance of the function is created using newkeyword (I wanted to enhance the user experience by adding some functionality when the passed argument in string format always returns its uppercased version, franceFrance . It’s not necessary but looks nicer).

sayHello() is a method of an object and, when called, thisrefers to the object itself. To prove this we can call typeof thisinside of the sayHello()function and will get object. We can also store a reference to the function inside of another variable. For instance

let greet = france.sayHello();
console.log(greet)

Whenever we call greet, it will point to the franceinstance of Countryclass function constructor. So we can say, that we store in this variable reference to function and later call this variable as a function.

Up to this moment, we implicitly bound this to an object. However, we can explicitly attach thisto certain values using apply(), call(), and bind().

When a method is passed as a callback function, we lose the receiver and this. To preserve thisfrom being lost, we can bind it to a specific object by using bind()method.

function person(){
console.log(`${this.name} is ${this.age} years old`) // this becomes the object it is called on
}
let john = {
name: "John",
age: 34
}
person.call(john) // John is 34 years old

First of all, we create personfunction which calls nameon this. At this point, it doesn’t know what thisrepresents. Second, we create an object with key-value pairs stored in the john variable. Third, we call()this john variable-object on personfunction thus binding this to johnobject. You can see how functions and variables are now connected and now thisis explicitly attached to the object it’s called upon. The same is genuinely true for apply(). The only difference is that apply()is used for arrays when call()is used for a comma-separated list of arguments.

bind()acts a bit differently. It allows us to permanently bind thisto a value. In the example below, we will create a function that is permanently bound to the object.

function person(){
console.log(`${this.name} is ${this.age} years old`) // this becomes the variable it is called on
}
let john = {
name: "John",
age: 34
}
person = person.bind(john)
person() // John is 34 years old

Thus we re-assign the person function and it is now permanently bound to the variable.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store