En guide til dette i JavaScript

Den thissøgeord hands-down er en af de mest udbredte og alligevel misforstået i JavaScript. Jeg prøver at ændre det i dag.

Lad os vende tilbage til de gode gamle skoledage, hvor vi lærte om pronomen.

Phelps svømmer hurtigt, fordi han vil vinde løbet.

Bemærk brugen af ​​pronomenet "han". Vi adresserer ikke direkte Phelps her, men bruger pronomenet han til at henvise til Phelps . På samme måde bruger JavaScript thisnøgleordet som referent til at henvise til objektet i sammenhæng, dvs. emnet .

Eksempel:

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

I ovenstående kode har vi et objekt, carder har egenskaberne make, model og fullName. Værdien af fullNameer en funktion, der udskriver bilens fulde navn ved hjælp af 2 forskellige syntakser.

  • Brug af this= & g t; this.make+” “ +this.model the this henviser til objektet i kontekst, hvor is car so this.make er effektiv ly car.make og så is this.model.
  • Ved hjælp af punktnotation kan vi få adgang til objekternes egenskaber car.make & car.model.

this er det!

Nu hvor vi har forstået, hvad der er, this og det er mest grundlæggende brug, lad os lave nogle tommelfingerregler, så vi altid kan huske.

thisNøgleordet JS henviser til det objekt, det tilhører.

var car={make:'....'func:()=>{console.log(this.make)}}

I this ovenstående uddrag tilhører objektbilen.

Det tager forskellige værdier afhængigt af brugen

  1. Inde i en metode.
  2. Inde i en funktion.
  3. Alene.
  4. I en begivenhed.
  5. call()og apply().

Inde i en metode

Når thisdet bruges i en metode, henviser det til ejerobjektet.

Funktioner defineret inde i et objekt kaldes metoder. Lad os tage vores bileksempel igen.

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

fullName()her er en metode. Den thisinde i denne metode tilhører car.

Inde i en funktion

this inde i en funktion er lidt kompliceret. Den første ting at forstå er, at funktioner, ligesom alle objekter har egenskaber, også har egenskaber. Hver gang denne funktion udføres, får den thisegenskaben, som er en variabel med værdien af ​​det objekt, der påberåber den.

dette er egentlig bare en genvejsreference for det "forudgående objekt" - det påkaldende objekt. - javascriptissexy.com

Hvis funktionen ikke påberåbes af et objekt this , hører funktionen inde til det globale objekt, som kaldes vindue. I dette tilfælde refererer dette til de værdier, der er defineret i det globale omfang. Lad os se et eksempel for bedre forståelse:

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 Huracán window.fullName(); // Mclaren 720S fullName(); // Mclaren 720S

Her make, modelog fullName defineres globalt, mens car objektet også har en implementering fullName . Når det påberåbes af carobjektet henviste det til de egenskaber, der er defineret inde i objektet. På den anden side er de to andre funktionsopkald de samme og returnerer de globalt definerede egenskaber.

Alene

Når det bruges alene, ikke inde i nogen funktion eller objekt, this refererer det til det globale objekt.

Den this her refererer til den globale navn ejendommen.

I en begivenhed

Begivenheder kan være af enhver type, men lad os tage en klikbegivenhed af hensyn til enkelhed og klarhed.

Hver gang der klikkes på en knap, og en begivenhed hæves, kan den ringe til en anden funktion for at udføre en bestemt opgave baseret på klik. Hvis den this bruges inden for denne funktion, henviser den til det element, der rejste begivenheden. I DOM gemmes alle elementerne som objekter. Det er derfor, når en begivenhed hæves, det henviser til det element, fordi det webside-element faktisk er et objekt inde i DOM .

Eksempel:

 Remove Me!

ring (), anvend () & bind ()

  • bind: giver os mulighed for at indstille thisværdien på metoder.
  • call & apply: tillad os at låne funktioner og indstille thisværdi på funktionsopkald.

Call, Bind and Apply er i sig selv et emne for et andet indlæg. De er meget vigtige, og det er ikke muligt at forklare dem her, da vi skulle vide alt om this at kende brugen af ​​disse funktioner.

Den sværeste del

Hvis det forstås godt, skal du thisgøre vores arbejde lettere på en måde. Men der er nogle tilfælde, hvor det misforstås.

Eksempel 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();

Vi får et uventet resultat her. Vi lånte en metode, der bruger this fra et andet objekt, men problemet her er, at metoden kun er tildelt anotherCar funktion, men faktisk påberåbes på car objektet. Derfor får vi resultatet som Lamborghini og ikke Ferrari.

For at løse dette bruger vi call() metoden.

Her call()metodekald fullName()anotherCar objekt, som oprindeligt ikke har fullName()funktionen.

We can also see that, when we log the car.name and anotherCar.name we get the result for the latter not on former, which means that the function was indeed invoked on anotherCar and not on 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()

In the above snippet we have a global object called cars and we have the same name object inside the car object. The fullName() method is then assigned to the vehicle variable which is then called. The variable belongs to the global object so this calls the global cars object instead of the cars object because of the context.

To resolve that we use .bind() function to solve the issue.

Binding helps us with specifically setting the this value and hence the vehicle variable explicitly points to the car object and not the global object, so this lies in the context of the car object.

Example 3.

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

In the above snippet, the fullName() calls upon a function which iterated through the cars array using forEach. Inside the forEach there is an anonymous function where this loses context. A function inside a function in JavaScript is called a closure. Closures are very important and widely used in JavaScript.

Another important concept playing a role here is scope. A variable inside a function cannot access variables and properties outside its scope. this inside the anon function cannot access this outside it. So this has nowhere to go but to point to global object. But there, no property is defined for this to access so undefined is printed.

A workaround for the above is that we can assign a variable the value of this, outside the anonymous function and then use it inside it.

Here, the self variable contains the value of this which is used with the inner function thus giving us the output.

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']);

This is a revisited example, in which this wasn't accessible so we preserved it's value by using a variable called self. Let's use arrow function to solve the same:

As you can see, using an arrow function in forEach() automatically solves the problem and we don’t have to do bind, or give the this value to some other variable. This is because arrow functions bind their context so this actually refers to the originating context, or the originating 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);

The above code consists of two identical objects, with one containing a callback function. A callback function is a function passed into another function as an argument, which is then invoked inside the outer function to complete some kind of routine.

Here, the truck object’s fullName method consists of a callback which is also invoked inside it. Our car object is as before. When we invoke the truck’s fullName method with the callback(argument) as the fullName method of the car object, we get output as Tesla Truck and undefined undefined.

After reading about this some of you might have gotten a hunch that car.fullName would print the model and make of the truck object, but to your disappointment, this again played a trick on us. Here the car.fullName is passed as an argument and is not actually invoked by the truck object. The callback invokes the car object method, but note that the actual call site for the function is the callback which binds this to the global object. It's a bit confusing, so read it again!

Here to get clarity, we print this itself. We can see that the this of callback is given a global scope. So to get a result we create global make and model properties.

Again, running the same code with global make and model properties we finally get the answer to the global this. This proves that this references the global object.

To get the results which we desire, the car.fullName result we will again use bind() to hard-bind the car object to the callback, which will make everything right again.

Solved!

No doubt that this is very useful, but has it's own pitfalls too. Hope I made it quite easy for you to understand. If you want more content simplified like this, follow me on Medium. Please leave your responses and share this if you liked it.