Är du bland de JavaScript-utvecklare som tycker att nyckelordet "detta" är förbryllande? Den här guiden är här för att reda ut all förvirring du kan ha om det.
Vad gör detta nyckelord i JavaScript betyder? Och hur kan du använda det praktiskt i ditt JavaScript-program? Det här är några av de vanligaste frågorna som nybörjare och till och med några erfarna JavaScript-utvecklare ställer om detta nyckelord.
Om du är en av dessa utvecklare som undrar vad detta nyckelord handlar om, då är den här artikeln för dig. Utforska vad detta hänvisar till i olika sammanhang och bekanta dig med några gotchas för att undvika förvirring, och naturligtvis, buggar i din kod.
"det här" inom det globala omfattningen
I det globala sammanhanget, detta kommer att returnera fönster objekt så länge det är utanför en funktion. Global kontext innebär att du inte placerar den i en funktion.
if(true) {
console.log(this) // returns window object
}
let i = 2
while(i < 10) {
console.log(this) // returns window object till i 9
i++
}
Om du kör ovanstående kod får du fönsterobjektet.
"detta" inre funktioner (metoder)
När det används inuti funktioner, detta hänvisar till objektet som funktionen är bunden till. Undantaget är när du använder detta i en fristående funktion, i så fall returnerar den fönster objekt. Låt oss se några exempel.
I följande exempel är säg Namn funktionen finns inuti mig objekt (dvs. det är en metod). I sådana här fall, detta hänvisar till objektet som innehåller funktionen.
functionsayName() {
return`My name is ${this.name}`
}const me = {
name: "Kingsley",
sayName: sayName
}
console.log(me.sayName()) // My name is Kingsley
detta är mig objekt, så att säga detta namnet inuti säg Namn metoden är exakt densamma som mig.namn.
Ett annat sätt att tänka på det är att det som finns på vänster sida av funktionen när den anropas kommer att vara det detta. Detta innebär att du kan återanvända säg Namn funktion i olika objekt och detta kommer att referera till ett helt annat sammanhang varje gång.
Nu, som tidigare nämnt, detta returnerar fönster objekt när det används i en fristående funktion. Detta beror på att en fristående funktion är bunden till fönster objekt som standard:
functiontalk() {
returnthis
}
talk() // returns the window object
Kallelse prata() är detsamma som att ringa window.talk(), och allt som finns på vänster sida av funktionen blir automatiskt detta.
På en sidoanteckning, den detta nyckelordet i funktionen beter sig annorlunda i JavaScripts strikta läge (det återkommer odefinierad). Detta är också något att tänka på när du använder UI-bibliotek som använder strikt läge (t.ex. React).
Använda "detta" med Function.bind()
Det kan finnas scenarier där du inte bara kan lägga till funktionen till ett objekt som en metod (som i förra avsnittet).
Kanske är föremålet inte ditt och du hämtar det från ett bibliotek. Objektet är oföränderligt, så du kan inte bara ändra det. I fall som detta kan du fortfarande köra funktionssatsen separat från objektet med hjälp av Function.bind() metod.
I följande exempel är säg Namn funktion är inte en metod på mig objekt, men du band det fortfarande med hjälp av binda() fungera:
functionsayName() {
return`My name is ${this.name}`
}const me = {
name: "Kingsley"
}const meTalk = sayName.bind(me)
meTalk() // My name is Kingsley
Vilket föremål du än passerar in i binda() kommer att användas som värdet av detta i det funktionsanropet.
Sammanfattningsvis kan du använda binda() på valfri funktion och passera i ett nytt sammanhang (ett objekt). Och det objektet kommer att skriva över innebörden av detta inuti den funktionen.
Använda "detta" med Function.call()
Vad händer om du inte vill returnera en helt ny funktion, utan hellre bara anropa funktionen efter att ha bindit den till sitt sammanhang? Lösningen för det är ring upp() metod:
functionsayName() {
return`My name is ${this.name}`
}const me = {
name: "Kingsley"
}
sayName.call(me) // My name is Kingsley
De ring upp() metod kör omedelbart funktionen istället för att returnera en annan funktion.
Om funktionen kräver en parameter kan du skicka den via ring upp() metod. I följande exempel skickar du språket till sayName() funktion, så att du kan använda den för att villkorligt returnera olika meddelanden:
functionsayName(lang) {
if (lang "en") {
return`My name is ${this.name}`
} elseif (lang "it") {
return`Io sono ${this.name}`
}
}const me = {
name: "Kingsley"
}
sayName.call(me, 'en') // My name is Kingsley
sayName.call(me, 'it') // Io sono Kingsley
Som du kan se kan du bara skicka vilken parameter du vill till funktionen som det andra argumentet till ring upp() metod. Du kan också skicka så många parametrar som du vill.
De tillämpa() metoden är mycket lik ring upp() och binda(). Den enda skillnaden är att du skickar flera argument genom att separera dem med ett kommatecken med ring upp(), medan du skickar flera argument inuti en array med tillämpa().
Sammanfattningsvis, bind(), call() och applicera() alla låter dig anropa funktioner med ett helt annat objekt utan att ha någon form av relation mellan de två (dvs funktionen är inte en metod på objektet).
"detta" Inside Constructor Functions
Om du anropar en funktion med en ny nyckelord, skapar det en detta objekt och returnerar det:
functionperson(name){
this.name = name
}const me = new person("Kingsley")
const her = new person("Sarah")
const him = new person("Jake")
me.name // Kingsley
her.name // Sarah
him.name // Jake
I ovanstående kod skapade du tre olika objekt från samma funktion. De ny nyckelord skapar automatiskt en bindning mellan objektet som skapas och detta nyckelord i funktionen.
"detta" Inside Callback-funktioner
Återuppringningsfunktioner är skiljer sig från vanliga funktioner. Återuppringningsfunktioner är funktioner som du skickar till en annan funktion som ett argument, så de kan köras direkt efter att den huvudsakliga har körts klart.
De detta nyckelord hänvisar till ett helt annat sammanhang när det används i återuppringningsfunktioner:
functionperson(name){
this.name = name
setTimeout(function() {
console.log(this)
}, 1000)
}
const me = new person("Kingsley") // returns the window object
Efter en sekunds uppringning person konstruktörsfunktion och skapa en ny mig objekt loggar det fönsterobjektet som värdet av detta. Så när den används i en återuppringningsfunktion, detta hänvisar till fönsterobjektet och inte det "konstruerade" objektet.
Det finns två sätt att fixa detta. Den första metoden är att använda binda() att binda person funktion till det nybyggda objektet:
functionperson(name){
this.name = name
setTimeout(function() {
console.log(this)
}.bind(this), 1000)
}
const me = new person("Kingsley") // returns the me object
Med ovanstående ändring, detta i återuppringningen kommer att peka på detsamma detta som konstruktorfunktionen (den mig objekt).
Det andra sättet att lösa problemet med detta i callback-funktioner är genom att använda pilfunktioner.
"detta" Inside Arrow Functions
Pilfunktioner skiljer sig från vanliga funktioner. Du kan göra din återuppringningsfunktion till en pilfunktion. Med pilfunktioner behöver du inte längre binda() eftersom det automatiskt binder till det nykonstruerade objektet:
functionperson(name){
this.name = name
setTimeout(() => {
console.log(this)
}, 1000)
}
const me = new person("Kingsley") // returns the me object
Lär dig mer om JavaScript
Du har lärt dig allt om nyckelordet "det här" och vad det betyder i alla olika sammanhang i JavaScript. Om du är ny på JavaScript kommer du att ha stor nytta av att lära dig alla grunderna i JavaScript och hur det fungerar.