A Guide to This in JavaScript by Ashay Mandwarya This has always been a key and difficult point in JavaScript. With the help of this article, we can get to know and understand this again and deepen our impression.

This is undoubtedly the most widely used yet misunderstood keyword in JavaScript, and I’ll explain it in detail today.

When we learn English pronouns at school:

Phelps is swimming fast because he wants to win the race.

In this sentence, we don’t use Phelps directly, but use the pronoun “he” to refer to him. Similarly, JavaScript uses the this keyword to point to objects in a reference context.

Ex. :

var car = {
    make: "Lamborghini".model: "Huracán".fullName: function () {
        console.log(this.make + "" + this.model); 
        console.log(car.make + "" + car.model); 
    }
}
car.fullName();

/ / Lamborghini Huracan
/ / Lamborghini Huracan
Copy the code

In the above code, we define an object car with attributes make, Model, and fullName, where fullName is a function that outputs make and Model using two different methods.

  • usethisWhen,this.make+ " " +this.modelIn thethisRefers to objects in context, i.ecar,this.makecar.make.this.modelcar.model;
  • With the dot operator, we can directly access the properties of an objectcar.makecar.model.

this

Now that we know what this is and its most basic uses, we’ll list some scenarios and illustrate them for your convenience.

According to the position of occurrence, this can be divided into the following situations:

  1. Use within a method
  2. Inside a function
  3. Exist alone
  4. Used in events
  5. call()apply()

1. Use within methodsthis

When used within a method, this refers to the object to which it belongs.

Functions defined within an object are called methods. Let’s look at the car example:

var car = {
    make: "Lamborghini".model: "Huracán".fullName: function () {
        console.log(this.make + "" + this.model);
        console.log(car.make + "" + car.model);
    }
}
car.fullName();
Copy the code

In this case, fullName() is the method in which this refers to the object CAR.

2. Use within functionsthis

The function this is a little bit more complicated. Functions, like objects, have attributes. The function gets this every time it executes, pointing to the object that called it.

This is really just a quick reference to the antecedent object, the object call. – javascriptissexy.com

If the function is not called by an object, the this inside the function belongs to the global object, which is called window. In this case, this will point to a variable in the global scope. Consider the following examples:

var make = "Mclaren";
var model = "720s"
function fullName() {
    console.log(this.make + "" + this.model);
}
var car = {
    make: "Lamborghini".model: "Huracán".fullName: function () {
        console.log(this.make + "" + this.model);
    }
}
car.fullName(); / / Lmborghini Huracan
window.fullName(); // Mclaren 720S
fullName(); // Mclaren 720S
Copy the code

In this example, make, Model, and fullName are defined in the global object, and the fullName method is implemented in the object CAR. When the method is called with CAR, this refers to a variable within the object; With the other two calls, this points to the global variable.

3. Use alonethis

When this is used alone and not attached to any function or object, it points to a global object.

Here this refers to the global variable name.

4. Use within eventsthis

There are many types of events in JS, but for simplicity we’ll use click events as an example.

Each time a button is clicked and an event is triggered, another function can be called to perform a task. If you use this inside a function, it refers to the element in the event that triggered it. In the DOM, all elements are stored as objects, meaning that the web element is actually an object in the DOM, so every time an event is raised, this points to that element.

Ex. :

<button onclick="this.style.display='none'">
  Remove Me!
</button>
Copy the code

5. call(), apply() & bind()

  • bind: allows us to set in a methodthisPoint to the
  • call&apply: allows us to leverage other functions and change them in function callsthisPointing to.

Call (), apply(), and bind() will be covered in another article.

How to use apply(💅), call(📞), bind(➰) in JavaScript

The difficulties in

Understanding this will make your job a lot easier, but it’s not always that easy. Take a look at the following examples.

Case 1:

var car = {
    make: "Lamborghini".model: "Huracán".name: null.fullName: function () {
        this.name = this.make + "" + this.model;
        console.log(this.name); }}var anotherCar = {
    make: "Ferrari".model: "Italia".name: null
}
anotherCar.name = car.fullName();

/ / Lamborghini Huracan
Copy the code

The result was not what we expected. Analyze the reason for this: When we call a method on another object using this, we just assign the method to anotherCar, but the actual caller is car. So you return a Lamborghini instead of a Ferrari.

We can solve this problem using call().

In this example, the call() method is used to make anotherCar call fullName(), which does not have a fullName() method originally, but outputs Ferrari Italia.

In addition, when we print the values of car.name and anotherCar.name, the former outputs null, while the latter outputs Ferrari Italia, that is, the fullName() function is actually called by anotherCar. Instead of being called by CAR.

Example 2:

var cars = [
    { make: "Mclaren".model: "720s" },
    { make: "Ferrari".model: "Italia"}]var car = {
    cars: [{ make: "Lamborghini".model: "Huracán"}].fullName: function () {
        console.log(this.cars[0].make + "" + this.cars[0].model); }}var vehicle = car.fullName;
vehicle() // Mclaren 720s
Copy the code

In this example, we define a global variable CARS and a variable of the same name in the object CAR, then assign the fullName() method to the variable vehicle and call it. This variable is a global variable, and due to context, this refers to the global variable CARS instead of the local variable.

We can solve this problem using bind().

Bind changes the reference to this so that the variable vehicle points to the local variable car. That is, the reference to this depends on the context of the car.

Example 3:

var car = {
   cars: [{make: "Lamborghini".model: "Huracán" },
        { make: "Mclaren".model: "720s" },
        { make: "Ferrari".model: "Italia"}].brand:"lamborghini".fullName: function () {
        this.cars.forEach(function(car){
            console.log(car.model + "" + this.brand);
        })
    }
}
car.fullName();

/ / Huracan undefined
// 720s undefined
// Italia undefined
Copy the code

In the above code, fullName() iterates through the array cars using forEach, each iteration producing an anonymous function with no context. Such functions defined inside the function are called closures. Closures are very important in JavaScript and are widely used.

Another important concept is scope. Variables defined inside a function cannot access variables and attributes outside its scope; This in an anonymous function cannot access the external scope, so that this can only point to global objects. In this case, the brand attribute that this accesses is not defined in the global object, so undefined is printed.

The solution to the above problem is that we can assign this outside the anonymous function and then use it inside the function.

Assign this to the variable self, replacing this in the function body, and print the expected result.

Example 4:

var car = {
    make: "Lamborghini".model: "Huracán".fullName: function (cars) {
        cars.forEach(function (vehicle) {
            console.log(vehicle + "" + this.model);
        })
    }
}
car.fullName(['lambo'.'ferrari'.'porsche']);

// lambo undefined
// ferrari undefined
// porsche undefined
Copy the code

When this is not accessible, the variable self can be used to hold it (as in Example 3), but in this case the arrow function can also be used:

As you can see, using the arrow function in forEach() solves this problem rather than binding or staging this. This is because the arrow function is bound to the context, and this actually refers to the original context or the original object.

Example 5:

var car = {
    make: "Lamborghini".model: "Huracán".fullName: function () {
        console.log(this.make + "" + this.model); }}var truck = {
    make: "Tesla".model: "Truck".fullName: function (callback) {
        console.log(this.make + "" + this.model);
        callback();
    }
}
truck.fullName(car.fullName);

// Tesla Truck
// undefined undefined
Copy the code

Two identical objects are defined in the above code, but one of them contains a callback function that is passed as an argument to the other function and then done with an external function call.

The fullName method of the object truck in this code contains a callback function and is called directly in the method. When truck.fullname () is called with car.fullname as an argument, output Tesla truck and undefined.

The result was unexpected. In fact, car.fullname is only passed in as a parameter, not called by the Truck object. In other words, the callback calls the car method, but binds this to the global scope, as shown below:

We print this for ease of observation. You can see that this in the callback refers to the global scope. Continue creating the global variables make and model as follows:

Obviously, the global variables make and model are printed in the callback function, again proving that this refers to the global object.

To get the desired result, we will use bind() to force the car into the callback function. As follows:

Done!

There is no doubt that this is very useful, but not easy to understand. Hopefully through this article you can gradually understand how to use it.

If this article helps you, please like 👏 and follow 👣