denne artikel blev oprindeligt skrevet til DigitalOcean.
this
nøgleord er et meget vigtigt koncept i JavaScript, og også et særligt forvirrende for både nye udviklere og dem, der har erfaring med andre programmeringssprog. I JavaScript er this
en henvisning til et objekt., Objektet, som this
refererer til, kan variere, implicit baseret på om det er globalt, på et objekt eller i en konstruktør, og kan også variere eksplicit baseret på brug af Function
prototype metoder bind
, call
og apply
.
selvom this
er lidt af et komplekst emne, er det også et, der vises, så snart du begynder at skrive dine første JavaScript-programmer., Uanset om du prøver at få adgang til et element eller en begivenhed i Document Object-modellen (DOM), bygningskurser til skrivning i den objektorienterede programmeringsstil eller ved hjælp af egenskaberne og metoderne for almindelige objekter, vil du støde på this
.
i denne artikel lærer du, hvad this
refererer til implicit baseret på kontekst, og du lærer, hvordan du bruger bind
, call
, og apply
metoder til eksplicit at bestemme værdien af this
.,
Implicit Sammenhæng
Der er fire vigtigste sammenhænge, i hvilke værdien af this
kan implicit udledes:
- den globale sammenhæng
- som en metode inden for et objekt
- som konstruktør på en funktion eller klasse
- som en DOM-event handleren
Globale
I den globale sammenhæng, this
henviser til den globale objekt. Når du arbejder i en bro .ser, er den globale kontekst window
. Når du arbejder i Node.js, den globale kontekst er global
.,
Bemærk: Hvis du endnu ikke er bekendt med konceptet af anvendelsesområdet i JavaScript, skal du gennemgå Forståelse Variabler, Anvendelsesområde, og Løft i JavaScript.
for eksemplerne vil du øve koden i Bro .serens Udviklerværktøjskonsol. Læs hvordan du bruger JavaScript Developer Console, hvis du ikke er bekendt med at køre JavaScript-kode i Bro .seren.
Hvis du logger værdien af this
uden anden kode, vil du se, hvilket objekt this
refererer til.,
console.log(this)
Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
Du kan se, at this
er window
, som er det globale objekt for en bro .ser.
Ved at forstå variabler, omfang og hejsning i JavaScript lærte du, at funktioner har deres egen kontekst for variabler. Du kan blive fristet til at tro, at this
ville følge de samme regler inde i en funktion, men det gør det ikke. En funktion på øverste niveau bevarer stadig this
reference for det globale objekt.,
du skriver en funktion på topniveau eller en funktion, der ikke er forbundet med noget objekt, som denne:
function printThis() { console.log(this)}printThis()
Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
selv inden for en funktion, this
henviser stadig til window
, eller globalt objekt.
Når du bruger streng tilstand, vil konteksten af this
inden for en funktion i den globale kontekst imidlertid være undefined
.,
'use strict'function printThis() { console.log(this)}printThis()
undefined
generelt er det mere sikkert at bruge streng tilstand for at reducere sandsynligheden for, at this
har et uventet omfang. Sjældent vil nogen henvise tilwindow
objekt ved hjælp afthis
.
For mere information om streng tilstand og hvilke ændringer den foretager vedrørende fejl og sikkerhed, skal du læse dokumentationen til streng tilstand på MDN.,
en Objektmetode
en metode er en funktion på et objekt eller en opgave, som et objekt kan udføre. En metode bruger this
for at henvise til objektets egenskaber.
"The United States of America was founded in 1776."
I dette eksempel: this
er det samme som america
.
i et indlejret objekt henviser this
til metodens aktuelle objektomfang. I det følgende eksempel henviser this.symbol
inden for details
objekt til details.symbol
.,
"The symbol is the eagle and the currency is USD."
en anden måde at tænke på er, at this
henviser til objektet på venstre side af prikken, når man kalder en metode.
en Funktionskonstruktør
Når du bruger new
nøgleord, opretter det en forekomst af en konstruktørfunktion eller-klasse. Funktionskonstruktører var standardmetoden til at initialisere et brugerdefineret objekt, før class
syntaks blev introduceret i ECMAScript 2015-opdateringen til JavaScript., I forståelse klasser i JavaScript, vil du lære at oprette en funktion konstruktør og en tilsvarende klasse konstruktør.
"The United States of America was founded in 1776."
i denne sammenhæng er this
nu bundet til forekomsten af Country
, som er indeholdt i america
konstant.
en Klassekonstruktør
en konstruktør på en klasse fungerer på samme måde som en konstruktør på en funktion. Læs mere om ligheder og forskelle mellem funktionskonstruktører og ES6 klasser i Understanding klasser i JavaScript.,
this
i describe
– metoden henviser til forekomsten af Country
, som er america
.
"The United States of America was founded in 1776."
EN DOM Event Handleren
I browseren, er der en speciel this
kontekst for event-handlere. I en event handler kaldet af addEventListener
,this
vil henvise til event.currentTarget
., Mere ofte end ikke, at udviklere vil simpelthen bruge event.target
eller event.currentTarget
, som er nødvendige for at få adgang til elementer i den DOM, men da den this
reference ændringer i denne situation, er det vigtigt at vide.
i det følgende eksempel opretter vi en knap, tilføjer tekst til den og tilføjer den til DOM. Når vi logger værdien af this
inden for begivenhedshåndtereren, udskriver den målet.,
<button>Click me</button>
Når du indsætter dette i din bro .ser, vil du se en knap tilføjet til siden, der siger “Klik på mig”. Hvis du klikker på knappen, vil du se <button>Click me</button>
vises i din konsol, da du klikker på knappen logger elementet, som er selve knappen. Derfor, som du kan se, this
henviser til det målrettede element, hvilket er det element, vi tilføjede en begivenhedslytter til.,
Eksplicit Sammenhæng
I alle de foregående eksempler, værdien af this
var bestemt af sin sammenhæng—uanset om den er global, i et objekt i en konstrueret funktion eller klasse, eller på en DOM event handleren. Ved at bruge call
, apply
eller bind
kan du dog eksplicit bestemme, hvad this
skal henvise til.,
det er vanskeligt at definere nøjagtigt, hvornår man skal bruge call
, apply
, eller bind
, da det afhænger af dit programs kontekst. bind
kan være særligt nyttigt, når du vil bruge begivenheder til at få adgang til Egenskaber for en klasse inden for en anden klasse. For eksempel, hvis du skulle skrive et simpelt spil, kan du adskille brugergrænsefladen og I / O i en klasse og spillogikken og tilstanden i en anden., Tastetryk og klik, vil du bind
begivenhederne for at få adgang tilthis
værdien af spillogikklassen.
den vigtige del er at vide, hvordan man bestemmer, hvilket objekt this
henviser til, som du kan gøre implicit med det, du lærte i de foregående afsnit, eller eksplicit med de tre metoder, du vil lære næste.,
ring og anvend
call
og apply
er meget ens—de påberåber sig en funktion med en specificeret this
kontekst og valgfrie argumenter. Den eneste forskel mellem call
og apply
er, at call
kræver, at argumenterne videregives i en efter en, og apply
tager argumenterne som et array.,
i dette eksempel opretter vi et objekt og opretter en funktion, der refererer til this
, men har ingen this
kontekst.
"undefined was written by undefined"
siden summary
og book
har ingen forbindelse, påberåber summary
i sig selv vil kun udskrive undefined
, da det leder efter disse egenskaber på det globale objekt.,
Bemærk: forsøg på dette i streng tilstand ville resultere i
Uncaught TypeError: Cannot read property 'title' of undefined
, somthis
selv ville væreundefined
.
du kan Dog bruge call
og apply
for at påberåbe sig den this
forbindelse med book
funktion.,
summary.call(book)// or:summary.apply(book)
"Brave New World was written by Aldous Huxley."
der er nu en forbindelse mellem book
og summary
når disse metoder anvendes. Lad os bekræfte præcis, hvad this
er.
function printThis() { console.log(this)}printThis.call(book)// or:whatIsThis.apply(book)
{title: "Brave New World", author: "Aldous Huxley"}
i dette tilfælde bliver this
faktisk objektet bestået som et argument.
sådan er call
og apply
de samme, men der er en lille forskel., Ud over at være i stand til at videregive this
kontekst som det første argument, kan du også videregive yderligere argumenter igennem.
function longerSummary(genre, year) { console.log( `${this.title} was written by ${this.author}. It is a ${genre} novel written in ${year}.`, )}
med call
hver yderligere værdi, du vil videregive, sendes som et yderligere argument.,
longerSummary.call(book, 'dystopian', 1932)
"Brave New World was written by Aldous Huxley. It is a dystopian novel written in 1932."
Hvis du forsøger at sende de nøjagtige samme argumenter med apply
, sker dette:
longerSummary.apply(book, 'dystopian', 1932)
div>
Uncaught TypeError: CreateListFromArrayLike called on non-object at <anonymous>:1:15
i stedet for apply
skal du videregive alle argumenterne i et array.
longerSummary.apply(book, )
"Brave New World was written by Aldous Huxley. It is a dystopian novel written in 1932."
forskellen mellem at videregive argumenterne individuelt eller i et array er subtil, men det er vigtigt at være opmærksom på., Det kan være enklere og mere praktisk at bruge apply
, da det ikke ville kræve ændring af funktionsopkaldet, hvis nogle parameterdetaljer blev ændret.
Binder
Både call
og apply
er one-time bruger metoder—hvis du kalder metoden med this
forbindelse, at det vil have den, men den oprindelige funktion, vil forblive uændret.,
nogle gange, du måske nødt til at bruge en metode, der igen og igen med this
kontekst af et andet objekt, og i dette tilfælde kan du bruge bind
metode til at skabe en helt ny funktion med en eksplicit bundet this
.
const braveNewWorldSummary = summary.bind(book)braveNewWorldSummary()
"Brave New World was written by Aldous Huxley"
i dette eksempel, hver gang du ringer braveNewWorldSummary
, vil den altid returnere den originale this
værdi bundet til den., Forsøg på at binde en nythis
kontekst til det mislykkes, så du kan altid stole på en bundet funktion for at returnere denthis
værdi, du forventer.
selvom dette eksempel forsøger at binde braveNewWorldSummary
endnu en gang, bevarer den den oprindelige this
kontekst fra første gang den blev bundet.
Pilefunktioner
Pilefunktioner har ikke deres egen this
binding. I stedet går de op til det næste niveau af udførelse.,
det kan være nyttigt at bruge pilefunktionen i tilfælde, hvor du virkelig vil this
for at henvise til den ydre kontekst. For eksempel, hvis du havde en begivenhedslytter inde i en klasse, vil du sandsynligvis have this
for at henvise til en vis værdi i klassen.
i dette eksempel, vil du oprette og tilføje knappen til DOM som før, men klassen vil have en begivenhed lytter, der vil ændre tekstværdien af knappen, når der klikkes.
Hvis du klikker på knappen, ændres tekstindholdet til værdien buttonText
., Hvis du ikke havde brugt en pilefunktion her, ville this
være lig med event.currentTarget
, og du ville ikke kunne bruge den til at få adgang til en værdi inden for klassen uden eksplicit at binde den. Denne taktik bruges ofte på klassemetoder i rammer som React.
Konklusion
I denne artikel, du har lært om this
i JavaScript, og de mange forskellige værdier det måske er baseret på implicitte runtime bindende, og eksplicit bindende gennem bind
call
og apply
., Du lærte også om, hvordan manglen på this
binding i pilefunktioner kan bruges til at henvise til en anden kontekst. Med denne viden skal du være i stand til at bestemme værdien af this
i dine programmer.