forståelse af dette, Bind, ring og anvend i JavaScript

forståelse af dette, Bind, ring og anvend i JavaScript

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 thisuden anden kode, vil du se, hvilket objekt this refererer til.,

console.log(this)
Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}

Du kan se, at thiser 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, thishenviser stadig til window, eller globalt objekt.

Når du bruger streng tilstand, vil konteksten af thisinden 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 thisnu 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.,

thisi 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, som thisselv ville være undefined.

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 bookog 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 braveNewWorldSummaryendnu 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.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *