Denne artikkelen ble opprinnelig skrevet for DigitalOcean.
this
søkeord er et svært viktig begrep i JavaScript, og også et spesielt forvirrende ett til både nye utviklere og de som ikke har erfaring i andre programmeringsspråk. I JavaScript, this
er en referanse til et objekt., Objektet this
refererer til kan variere, implisitt basert på om det er global, og på et objekt, eller i en konstruktør, og kan også variere eksplisitt basert på bruk av Function
prototype metoder bind
, call
, og apply
.
Selv om this
er litt av et komplekst tema, det er også en som vises så snart du begynner å skrive din første JavaScript-programmer., Om du prøver å få tilgang til et element eller en hendelse på Document Object Model (DOM), bygge klasser for å skrive i objekt-orientert programmering stil, eller ved å bruke egenskaper og metoder for vanlige objekter, vil du møte this
.
I denne artikkelen, vil du lære hva som this
refererer til implisitt basert på kontekst, og du vil lære hvordan du kan bruke bind
, call
, og apply
metoder for å fastslå verdien av this
.,
Implisitt Kontekst
Det er fire viktigste sammenhenger hvor verdien av this
kan være implisitt utledes:
- den globale konteksten
- som en metode innen et objekt
- som en konstruktør på en funksjon eller klasse
- som en DOM hendelseshåndterer
Global
I den globale sammenheng, this
henviser til den globale objektet. Når du arbeider i en nettleser, global sammenheng er window
. Når du arbeider i Noden.js, den globale sammenheng er global
.,
Merk: Hvis du ennå ikke er kjent med konseptet av omfanget i JavaScript, kan du se Forstå Variabler, Omfang og Løfting i JavaScript.
For eksempler, du vil øve koden i nettleserens Verktøy for utviklere-konsollen. Les Hvordan du kan Bruke JavaScript-utviklerkonsollen hvis du ikke er kjent med kjøring av JavaScript-kode i nettleseren.
Hvis du logger verdien av this
uten noen annen kode, vil du se hva objektet this
refererer til.,
console.log(this)
Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
Du kan se at this
er window
, som er den globale objekt av en nettleser.
for å Forstå Variabler, Omfang og Løfting i JavaScript, du lært at funksjoner har sin egen kontekst for variabler. Du kan bli fristet til å tenke at this
ville følger de samme reglene inne i en funksjon, men det gjør det ikke. En topp-nivå funksjon vil fortsatt beholde this
referanse til den globale objektet.,
Du skrive en topp-nivå funksjon eller en funksjon som ikke er knyttet til noe objekt, som dette:
function printThis() { console.log(this)}printThis()
Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
Selv innenfor en funksjon, this
fortsatt refererer til window
eller globale objektet.
Imidlertid, når du bruker strengt modus, sammenheng med this
innenfor en funksjon på den globale sammenheng vil være undefined
.,
'use strict'function printThis() { console.log(this)}printThis()
undefined
Vanligvis, det er tryggere å bruke strenge modus for å redusere sannsynligheten for this
å ha en uventet omfang. Sjelden vil noen ønsker å se den window
objekt ved hjelp av this
.
For mer informasjon om strenge modus, og hvilke endringer det gjør om feil og sikkerhet, les Strenge modus dokumentasjon på MDN.,
Et Objekt Metode
en metode er En funksjon på et objekt, eller en oppgave som et objekt kan utføre. En metode som bruker this
for å se på egenskapene til gjenstanden.
"The United States of America was founded in 1776."
I dette eksempelet, this
er det samme som america
.
I en nestet objekt, this
refererer til gjeldende objekt omfanget av metoden. I følgende eksempel this.symbol
i details
objektet refererer til details.symbol
.,
"The symbol is the eagle and the currency is USD."
en Annen måte å tenke på om det er at this
refererer til objektet på venstre side av dot når du ringer til en metode.
En Funksjon Constructor
Når du bruker new
søkeord, det skaper en forekomst av en konstruktør funksjon eller klasse. Funksjonen konstruktører var den vanlige måten å opprette en bruker-definert objekt før class
syntaks ble innført i ECMAScript 2015 oppdatering til JavaScript., I Forståelse Klasser i JavaScript, vil du lære hvordan å lage en funksjon konstruktør og en tilsvarende klasse constructor.
"The United States of America was founded in 1776."
I denne sammenhengen, this
er nå bundet til forekomst av Country
, som er inneholdt i america
konstant.
En Klasse Constructor
En konstruktør på en klasse fungerer det samme som en konstruktør på en funksjon. Les mer om likheter og forskjeller mellom funksjon konstruktører og ES6 klasser i Forståelse Klasser i JavaScript.,
this
i describe
metode refererer til forekomst av Country
, som er america
.
"The United States of America was founded in 1776."
EN DOM hendelseshåndterer
I nettleseren, og det er en spesiell this
kontekst for event-handlere. I en event handler kalt av addEventListener
, this
vil du se event.currentTarget
., Oftere enn ikke, utviklere vil rett og slett bruke event.target
eller event.currentTarget
som trengs for å få tilgang til elementer i DOM, men siden this
referanse endringer i denne sammenheng er det viktig å vite.
I følgende eksempel skal vi lage en knapp, legge til tekst i den, og legge den til DOM. Når vi logger verdien av this
innenfor event handler, vil det skrives ut målet.,
<button>Click me</button>
Når du limer dette inn i nettleseren din, vil du se en knapp lagt til side som sier «Klikk meg». Hvis du klikker på knappen, vil du se <button>Click me</button>
vises i konsollen, som å klikke på knappen logg element, som er selve knappen. Derfor, som du kan se, this
viser til den målrettede element, som er det elementet vi lagt til en hendelse som lytter til.,
Eksplisitt Kontekst
I alle de tidligere eksempler, verdien av this
ble bestemt av sin sammenheng—enten det er global, i et objekt, i en konstruert funksjonen eller i en klasse, eller på en DOM hendelseshåndterer. Imidlertid, ved hjelp av call
, apply
, eller bind
, kan du eksplisitt fastslå hva som this
skal se.,
Det er vanskelig å definere nøyaktig når du skal bruke call
, apply
, eller bind
, som det vil være avhengig av konteksten av programmet. bind
kan være spesielt nyttig når du ønsker å bruke hendelsene til å få tilgang til egenskapene for en klasse i en annen klasse. For eksempel, hvis du var å skrive et enkelt spill, du kan skille brukergrensesnittet og I/O i én klasse, og spillet logikk og stat til en annen., Siden spillet logikk skulle trenge å få tilgang inndata, for eksempel tastetrykk og klikk du ønsker å bind
hendelser for å få tilgang til this
verdi av spillet logikk klasse.
Den viktigste delen er å vite hvordan å finne ut hva objektet this
refererer til, som du kan gjøre implisitt med det du lærte i forrige avsnitt, eller eksplisitt med de tre metodene vil du lære neste.,
Anrop, og Bruk
call
og apply
er svært like—de påkaller en funksjon med en bestemt this
sammenheng, og valgfrie argumenter. Den eneste forskjellen mellom call
og apply
at call
krever argumenter for å være gått i ett etter ett, og apply
tar de argumentene som en matrise.,
I dette eksempelet, vil vi opprette et objekt, og lage en funksjon som referanser this
men har ingen this
sammenheng.
"undefined was written by undefined"
Siden summary
og book
har ingen forbindelse, bruk summary
av seg selv bare vil skrive ut undefined
, som det er på utkikk etter disse egenskapene på det globale objektet.,
Merk: Forsøk på dette i streng-modus, vil resultere i
Uncaught TypeError: Cannot read property 'title' of undefined
somthis
seg selv ville væreundefined
.
du kan Imidlertid bruke call
og apply
for å aktivere this
kontekst av book
på-funksjon.,
summary.call(book)// or:summary.apply(book)
"Brave New World was written by Aldous Huxley."
Det er nå en forbindelse mellom book
og summary
når disse metodene er anvendt. La oss bekrefte nøyaktig hva this
er.
function printThis() { console.log(this)}printThis.call(book)// or:whatIsThis.apply(book)
{title: "Brave New World", author: "Aldous Huxley"}
I dette tilfellet, this
faktisk blir objektet som er sendt som et argument.
Dette er hvordan call
og apply
er den samme, men det er en liten forskjell., I tillegg til å være i stand til å passere this
kontekst som første argument, kan du også sende ytterligere argumenter gjennom.
function longerSummary(genre, year) { console.log( `${this.title} was written by ${this.author}. It is a ${genre} novel written in ${year}.`, )}
Med call
hver ekstra verdien som du ønsker å passere, er sendt som et ytterligere argument.,
longerSummary.call(book, 'dystopian', 1932)
"Brave New World was written by Aldous Huxley. It is a dystopian novel written in 1932."
Hvis du prøver å sende nøyaktig samme argumenter med apply
, dette er hva som skjer:
longerSummary.apply(book, 'dystopian', 1932)
Uncaught TypeError: CreateListFromArrayLike called on non-object at <anonymous>:1:15
i Stedet for apply
du må passere alle argumenter i en matrise.
longerSummary.apply(book, )
"Brave New World was written by Aldous Huxley. It is a dystopian novel written in 1932."
forskjellen mellom passerer argumenter individuelt eller i en matrise er subtil, men det er viktig å være klar over., Det kan være enklere og mer praktisk å bruke apply
, så ville det ikke nødvendig å endre funksjonen ring hvis noen parameter detaljer endret.
Binde
Begge call
og apply
er ett-tiden i bruk metoder—hvis du kaller metoden med this
sammenheng vil det ha den, men den opprinnelige funksjonen vil forbli uendret.,
noen Ganger, du må kanskje bruke en metode over og over med this
sammenheng med et annet objekt, og i det tilfellet kan du bruke bind
metode for å lage en helt ny funksjon med en eksplisitt bundet this
.
const braveNewWorldSummary = summary.bind(book)braveNewWorldSummary()
"Brave New World was written by Aldous Huxley"
I dette eksempel, hver gang du ringer braveNewWorldSummary
, det vil alltid gå tilbake til den opprinnelige this
verdi bundet til det., Å forsøke å binde en ny this
sammenheng, og det vil svikte, så du kan alltid stole på en innbundet-funksjonen for å gå tilbake this
verdi forventet.
Selv om dette eksemplet forsøker å binde braveNewWorldSummary
igjen, det beholder den opprinnelige this
kontekst fra første gang den ble bundet.
Pil Funksjoner
Pil-funksjonene som ikke har egne this
bindende. I stedet, de gå opp til neste nivå for gjennomføring.,
Det kan være nyttig å bruke pil-funksjon i tilfeller der du virkelig ønsker this
for å referere til den ytre konteksten. For eksempel, hvis du hadde en hendelse lytteren i en klasse, ville du sannsynligvis vil this
for å se noen verdi i klassen.
I dette eksempelet, vil du opprette og legge til knappen for å DOM som før, men klassen vil ha et arrangement lytteren som vil endre teksten verdi på knappen når du har klikket på.
Hvis du klikker på knappen, tekst-innhold vil endre verdien av buttonText
., Hvis du ikke hadde brukt en pil funksjon her, this
ville være lik event.currentTarget
, og du ville ikke være i stand til å bruke den til å få tilgang til en verdi i klassen uten eksplisitt å binde den. Denne taktikken er ofte brukt på klasse metoder i rammer som Reagerer.
Konklusjon
I denne artikkelen, har du lært om this
i JavaScript, og de mange ulike verdier det kan ha basert på implisitt runtime bindende, og eksplisitt bindende gjennom bind
, call
, og apply
., Du har også lært om hvordan mangel på this
bindende i pil-funksjoner kan brukes til å henvise til en annen kontekst. Med denne kunnskapen, du bør være i stand til å fastslå verdien av this
i dine programmer.