JavaScript `dette` Keyword + 5 vigtige bindende regler forklaret for JS begyndere
JavaScript's this
nøgleord er et af de sværeste aspekter af sproget at forstå. Men det er kritisk vigtigt for at skrive mere avanceret JavaScript-kode.
I JavaScript this
tillader nøgleordet os at:
- Genbrug fungerer i forskellige sammenhænge, og
- Identificer hvilket objekt du skal fokusere på, når en metode påberåbes.
Når det kommer til this
, er det vigtige spørgsmål at stille, hvor funktionen påberåbes. Fordi vi ikke ved, hvad der er i this
nøgleordet, før funktionen påberåbes.
Brugen af this
kan kategoriseres i fem forskellige binding
aspekter. I denne artikel vil vi lære om alle fem aspekter med eksempler.
For det første: Hvad er bindende?
I JavaScript er a Lexical Environment
, hvor din kode er fysisk skrevet. I eksemplet nedenfor er variabelnavnet lexically
inde i funktionen sayName()
.
function sayName() { let name = 'someName'; console.log('The name is, ', name); }
En Execution Context
henviser til den kode, der kører i øjeblikket, og alt andet, der hjælper med at køre den. Der kan være mange leksikale miljøer tilgængelige, men det, der kører i øjeblikket, styres af Execution Context .

Hver af udførelseskonteksterne indeholder en Environment Record
. Binding
i JavaScript betyder registrering af identifikatoren (variabel og funktionsnavn) i en bestemt miljøpost.
Bemærk: Binding
hjælper med at knytte identifikatoren (variabel og funktionsnavn) til this
nøgleordet for en execution context
.
Bare rolig, hvis du finder det lidt svært at forstå nu. Du får bedre forståelse, når vi fortsætter.
Regel nr. 1: Sådan fungerer JavaScript Implicit Binding
Implicit binding dækker de fleste brugssager til håndtering af this
nøgleordet.
I implicit binding skal du kontrollere, hvad der er til venstre for dot (.) -Operatoren ved siden af en funktion på indkaldelsestidspunktet. Dette bestemmer, hvad der this
er bindende for.
Lad os se på et eksempel for at forstå det bedre.
let user = { name: 'Tapas', address: 'freecodecamp', getName: function() { console.log(this.name); } }; user.getName();
Her this
er bundet til brugerobjektet. Vi ved dette, fordi vi til venstre for prikken (.) Operatøren ved siden af funktionen getName()
ser user
objektet. Så this.name
skal logge Tapas i konsollen.
Lad os se et andet eksempel for bedre at forstå dette koncept:
function decorateLogName(obj) { obj.logName = function() { console.log(this.name); } }; let tom = { name: 'Tom', age: 7 }; let jerry = { name: 'jerry', age: 3 }; decorateLogName(tom); decorateLogName(jerry); tom.logName(); jerry.logName();
I dette eksempel har vi to objekter, tom
og jerry
. Vi har dekoreret (forbedret) disse objekter ved at vedhæfte en metode kaldet logName()
.
Bemærk, at når vi påberåber sig tom.logName()
, er tom
objektet til venstre for prik (.) Operatoren ved siden af funktionen logName()
. Så this
er bundet til tom
objektet, og det logger værdien tom ( this.name
er lig med tom her). Det samme gælder, når jerry.logName()
det påberåbes.
Regel nr. 2: Sådan fungerer eksplicit bindende JavaScript
Vi har set, at JavaScript skaber et miljø til at udføre den kode, vi skriver. Det tager sig af hukommelsesoprettelsen til variabler, funktioner, objekter og så videre i oprettelsesfasen . Endelig udfører den koden i udførelsesfasen . Dette specielle miljø kaldes Execution Context
.
Der kan være mange sådanne miljøer (Execution Contexts) i en JavaScript-applikation. Hver udførelseskontekst fungerer uafhængigt af de andre.
Men til tider vil vi måske bruge ting fra en eksekveringskontekst i en anden. Det er her, eksplicit binding kommer i spil.
I eksplicit binding kan vi kalde en funktion med et objekt, når funktionen er uden for objektets eksekveringskontekst.
Der er tre meget specielle metoder call()
, apply()
og bind()
som hjælper os med at opnå eksplicit binding.
Sådan call()
fungerer JavaScript- metoden
Med call()
metoden vil den kontekst, som funktionen skal kaldes til, blive videregivet som en parameter til call()
. Lad os se, hvordan det fungerer med et eksempel:
let getName = function() { console.log(this.name); } let user = { name: 'Tapas', address: 'Freecodecamp' }; getName.call(user);
Her call()
kaldes metoden på en kaldet funktion getName()
. Den getName()
funktion bare logger this.name
. Men hvad er this
her? Det bestemmes af, hvad der er sendt til call()
metoden.
Her this
vil binde til brugerobjektet, fordi vi har sendt brugeren som en parameter til call()
metoden. Så this.name
skal logge værdien af brugeregenskabets navnegenskab, det vil sige Tapas .
In the above example, we have passed just one argument to call()
. But we can also pass multiple arguments to call()
, like this:
let getName = function(hobby1, hobby2) { console.log(this.name + ' likes ' + hobby1 + ' , ' + hobby2); } let user = { name: 'Tapas', address: 'Bangalore' }; let hobbies = ['Swimming', 'Blogging']; getName.call(user, hobbies[0], hobbies[1]);
Here we have passed multiple arguments to the call()
method. The first argument must be the object context with which the function has to be invoked. Other parameters could just be values to use.
Here I am passing Swimming and Blogging as two parameters to the getName()
function.
Did you notice a pain point here? In case of a call()
, the arguments need to be passed one by one – which is not a smart way of doing things! That's where our next method, apply()
, comes into the picture.
How the JavaScript apply()
Method Works
This hectic way of passing arguments to the call()
method can be solved by another alternate method called apply()
. It is exactly the same as call()
but allows you to pass the arguments more conveniently. Have a look:
let getName = function(hobby1, hobby2) { console.log(this.name + ' likes ' + hobby1 + ' , ' + hobby2); } let user = { name: 'Tapas', address: 'Bangalore' }; let hobbies = ['Swimming', 'Blogging']; getName.apply(user, hobbies);
Here we are able to pass an array of arguments, which is much more convenient than passing them one by one.
Tip: When you only have one value argument or no value arguments to pass, use call()
. When you have multiple value arguments to pass, use apply()
.
How The JavaScript bind()
Method Works
The bind()
method is similar to the call()
method but with one difference. Unlike the call()
method of calling the function directly, bind()
returns a brand new function and we can invoke that instead.
let getName = function(hobby1, hobby2) { console.log(this.name + ' likes ' + hobby1 + ' , ' + hobby2); } let user = { name: 'Tapas', address: 'Bangalore' }; let hobbies = ['Swimming', 'Blogging']; let newFn = getName.bind(user, hobbies[0], hobbies[1]); newFn();
Here the getName.bind()
doesn't invoke the function getName()
directly. It returns a new function, newFn
and we can invoke it as newFn()
.
Rule #3: The JavaScript new
Binding
A new
keyword is used to create an object from the constructor function.
let Cartoon = function(name, animal) { this.name = name; this.animal = animal; this.log = function() { console.log(this.name + ' is a ' + this.animal); } };
You can create objects using the new
keyword like this:
let tom = new Cartoon('Tom', 'Cat'); let jerry = new Cartoon('Jerry', 'Mouse');
The constructor function's new binding rule states that, when a function is invoked with the new keyword, the this keyword inside the function binds to the new object being constructed.
Sounds complex? Ok, let's break it down. Take this line,
let tom = new Cartoon('Tom', 'Cat');
Here the function Cartoon is invoked with the new
keyword. So this
will be bound to the new object being created here, which is tom.
Rule #4: JavaScript Global Object Binding
What do you think will be the output of the code below? What is this
binding to here?
let sayName = function(name) { console.log(this.name); }; window.name = 'Tapas'; sayName();
If the this
keyword is not resolved with any of the bindings, implicit
, explicit
or new
, then the this
is bound to the window(global)
object.
There is one exception though. JavaScript strict mode does not allow this default binding.
"use strict"; function myFunction() { return this; }
In the above case, this
is undefined.
Rule #5: HTML Event Element Binding in JavaScript
In HTML event handlers, this
binds to the HTML elements that receive the event.
Click Me!
The is the output log in the console when you click on the button:
"Click Me!"
You can change the button style using the this
keyword, like this:
Click Me!
But be mindful when you call a function on the button click and use this
inside that function.
Click Me!
and the JavaScript:
function changeColor() { this.style.color='teal'; }
The above code won't work as expected. As we have seen in the Rule 4, here this
will be bound to the global object (in the 'non-strict' mode) where there is no style object to set the color.
In Summary
To summarize,
- In the case of implicit binding,
this
binds to the object to the left of the dot(.) operator. - In the case of explicit binding, we can call a function with an object when the function is outside of the execution context of the object. The methods
call()
,apply()
, andbind()
play a big role here. - When a function is invoked with the
new
keyword, thethis
keyword inside the function binds to the new object being constructed. - When the
this
keyword is not resolved with any of the bindings,implicit
,explicit
ornew
, thenthis
is bound to thewindow(global)
object. In JavaScript's strict mode,this
will be undefined. - In HTML event handlers,
this
binds to the HTML elements that receive the event.
There is one more case where this
behaves differently, such as with ES6 arrow function
s. We will take a look at that in a future article.
I hope you found this article insightful. You may also like,
- JavaScript Hoisting Internals
- Understanding JavaScript Execution Context like never before
- JavaScript Scope Fundamentals with Tom and Jerry
- Understanding JavaScript Closure with example
Hvis denne artikel var nyttig, bedes du dele den, så andre også kan læse den. Du kan @ mig på Twitter (@tapasadhikary) med kommentarer eller være velkommen til at følge mig.