Forstå Dette, Binde, Samtale, og Gjelder i JavaScript

Forstå Dette, Binde, Samtale, og Gjelder i JavaScript

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 som this seg selv ville være undefined.

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.

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *